Background : I have built a VB .NET application on the 4.0 Framework, part of the primary functionality is the built in AxWMPLib.AxWindowsMediaPlayer which allows us to pass a file path as a URL to the player and then play it through the built in media player. My Development Platform is VS 2010 Pro on Windows 7.
Problem: We have recently moved to testing this application on multiple OS's. The Application runs fine on Win 7 on multiple win7 machines, some used for development others not. The problem is when we run the application on Vista. the very first time the application tries to play a file after it has been opened it will throw an error
It does this the majority of times, but not always, and I have been unable to establish a pattern for the few times it has not thrown the error. Additionally, it only does this for the first file it plays not for subsequent files. And it eludes Try catches for error handling.
Research: I have done a good bit of research on this issue. I have found it seems to plague other media players and websites, even WMP on some machines. Some articles point to specific Windows KB updates, others suggest running a repair disk to repair potentially bad dlls. I have tried many of these unsuccessfully, as the issue persists on the two Vista machines I have to test with.
Code : here is the method that is called when this error occurs
Public Sub playSelected(ByVal fileStr As String) If File.Exists(fileStr) Then Debugging.DebugPrint(" Play: " & fileStr) MediaPlayer.URL = fileStr Try MediaPlayer.Ctlcontrols.play() Catch ex As Exception MessageBox.Show("Could Not play the selected File please try again. Exception : " + ex.Message) End Try Else Debugging.DebugPrint(" File Does not Exist: " & fileStr) End If End Sub
Purpose: I am hoping to find a way to handle this exception through code, potential previewing or sniping it if it is being thrown from one of the .NET controls i'm using. I would rather handle this via code if possible. If someone also has additional information on this specific error that would be welcome as well.
With credit to jornare for the information and push in the right direction I will explain my resolution, and the code behind it below, hope it helps.
First I had to modify the recommended answer, in a few distinct ways. The following two lines are declared in the class that calls the playSelected method above.
Public Declare Function SetErrorMode Lib "kernel32.dll" (ByVal uMode As System.UInt32) As System.UInt32 Private Const SEM_FAILCRITICALERRORS As System.UInt32 = &H1
you'll see the addition of the Const variable named SEM_FAILCRITICALERRORS, this is necessary to set the value of the variable to 1, in this case the name of the variable is very specific as it matches a flag var name in the SetErrorMode method, when set to true this flag disables CriticalErrors from showing. I also added the .dll ext to the Lib call, though it may not be necessary.
Below is my new playSelected method
Public Sub playSelected(ByVal fileStr As String) If File.Exists(fileStr) Then If isVista Then oldErrMode = SetErrorMode(SEM_FAILCRITICALERRORS) End If Debugging.DebugPrint(" Play: " & fileStr) MediaPlayer.URL = fileStr Try MediaPlayer.Ctlcontrols.play() Catch ex As Exception MessageBox.Show("Could Not play the selected File please try again. Exception : " + ex.Message) End Try If isVista Then criticalFailureTimer.Interval = 2000 criticalFailureTimer.AutoReset = False criticalFailureTimer.Start() End If Else Debugging.DebugPrint(" File Does not Exist: " & fileStr) End If End Sub
now this is important! Initially I SetErrorMode back to the oldErrMode after the ctlcontrols.play call, but found this did not prevent the error. I set my VS in debug mode on my win7 machine and stepped through the code line by line. I found the code did not actually try to play the file until after the sub ended. This is why you see the timer calls. I set a 2 second timer to give myself a buffer so it could start the playing process with the Error Mode set correctly. below is the code I used for the timer elapsed event
'in my Constructor If My.Computer.Info.OSFullName.Contains("Vista") Then isVista = True AddHandler criticalFailureTimer.Elapsed, AddressOf criticalTimerExpired End If 'end of Constructor portion Private Sub criticalTimerExpired(sender As Object, e As ElapsedEventArgs) SetErrorMode(oldErrMode) End Sub
One last caveat I will give for this. This process to my understanding disables Critical Errors from being displayed, so be careful, in my case I was unable to find any specific error or system instability caused by the error thrown, so I temporarily disable this to add to usability of the program. I do not recommend doing this everytime you have a system error as often that error points to a flaw/bug in the program that should be fixed. Additionally, in my opinion you should never need to turn off critical errors permanently, meaning make sure you turn them back on when you're done. I hope this information helps and appreciate the time and knowledge of those who answered or up-voted the question.
From what I find on the net it could be caused by a faulty WMP plugin, codek or display drivers. Found also that you should be able to suppress this error by calling the Windows API function SetErrorMode(SEM_FAILCRITICALERRORS) before WMP starts loading the media file.
So, for Vb something like:
'declare Private Declare Function SetErrorMode Lib "kernel32" (ByVal wMode As Long) As Long 'call it Dim oldErrMode As Long oldErrMode = SetErrorMode(SEM_FAILCRITICALERRORS) 'Do your stuff here 'Set it back SetErrorMode(oldErrMode )
I haven't tested this, so let me know if this helps.