I'm trying to understand what is it in the implementation of SoundPlayer.Play
that doesn't allow playing more than 1 sound async (eg, as explained here or here ). I looked into its source code , but I couldn't figured it out.
For convenience, here's the code of both SoundPlayer.Play
and SoundPlayer.LoadAndPlay
, which is the method called by SoundPlayer.Play
:
public void Play() {
LoadAndPlay(NativeMethods.SND_ASYNC);
}
private void LoadAndPlay(int flags) {
//
if (String.IsNullOrEmpty(soundLocation) && stream == null) {
SystemSounds.Beep.Play();
return;
}
if (uri != null && uri.IsFile) {
// VSW 580992: With more than one thread, someone could call SoundPlayer::set_Location
// between the time LoadAndPlay demands FileIO and the time it calls PlaySound under elevation.
//
// Another scenario is someone calling SoundPlayer::set_Location between the time
// LoadAndPlay validates the sound file and the time it calls PlaySound.
// The SoundPlayer will end up playing an un-validated sound file.
// The solution is to store the uri.LocalPath on a local variable
string localPath = uri.LocalPath;
// request permission to read the file:
// pass the full path to the FileIOPermission
FileIOPermission perm = new FileIOPermission(FileIOPermissionAccess.Read, localPath);
perm.Demand();
// play the path
isLoadCompleted = true;
System.Media.SoundPlayer.IntSecurity.SafeSubWindows.Demand();
System.ComponentModel.IntSecurity.UnmanagedCode.Assert();
// ValidateSoundFile calls into the MMIO API so we need UnmanagedCode permissions to do that.
// And of course we need UnmanagedCode permissions to all Win32::PlaySound method.
try {
// don't use uri.AbsolutePath because that gives problems when there are whitespaces in file names
ValidateSoundFile(localPath);
UnsafeNativeMethods.PlaySound(localPath, IntPtr.Zero, NativeMethods.SND_NODEFAULT | flags);
} finally {
System.Security.CodeAccessPermission.RevertAssert();
}
} else {
LoadSync();
ValidateSoundData(streamData);
System.Media.SoundPlayer.IntSecurity.SafeSubWindows.Demand();
System.ComponentModel.IntSecurity.UnmanagedCode.Assert();
try {
UnsafeNativeMethods.PlaySound(streamData, IntPtr.Zero, NativeMethods.SND_MEMORY | NativeMethods.SND_NODEFAULT | flags);
} finally {
System.Security.CodeAccessPermission.RevertAssert();
}
}
}
UnsafeNativeMethods.PlaySound(winmm.dll)仅允许在每个过程的特定时间播放单个声音。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.