问题我们最近开始在多个操作系统上测试这个应用程序.应用程序在多个win7机器上的Win 7上运行良好,一些用于开发其他机器.问题是我们在Vista上运行应用程序.应用程序第一次尝试在文件打开后播放它会引发错误
它大部分时间都这样做,但并非总是这样,而且我几次无法建立一个模式,它没有抛出错误.此外,它仅针对后续文件播放的第一个文件执行此操作.它避免了Try catchs的错误处理.
ResearchI对这个问题做了很多研究.我发现它似乎困扰着其他媒体播放器和网站,甚至是某些机器上的WMP.有些文章指向特定的Windows KB更新,其他文章建议运行修复磁盘来修复可能有害的dll.我已经尝试了其中许多失败,因为问题仍然存在于我必须测试的两台Vista机器上.
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
目的我希望找到一种方法来处理这个异常,通过代码,潜在的预览或狙击它,如果它是从我正在使用的.NET控件之一抛出.如果可能的话,我宁愿通过代码处理这个.如果有人也有关于此特定错误的其他信息,也会受到欢迎.
解析度
随着信息向jornare提供信息并向正确的方向发展,我将解释我的解决方案,以及它背后的代码,希望它有所帮助.
首先,我必须以几种不同的方式修改建议的答案.在调用上面的playSelected方法的类中声明了以下两行.
Public Declare Function SetErrorMode Lib "kernel32.dll" (ByVal uMode As System.UInt32) As System.UInt32 Private Const SEM_FAILCRITICALERRORS As System.UInt32 = &H1
您将看到添加名为SEM_FAILCRITICALERRORS的Const变量,这是将变量的值设置为1所必需的,在这种情况下,变量的名称非常具体,因为它与SetErrorMode方法中的标志var名称匹配,当设置为true此标志禁用CriticalErrors显示.我还将.dll ext添加到了Lib调用中,尽管可能没有必要.
下面是我的新playSelected方法
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
现在这很重要!最初我在Ctlcontrols.play调用之后将SetErrorMode返回到oldErrMode,但发现这并没有阻止错误.我在我的win7机器上以调试模式设置我的VS并逐行逐步执行代码.我发现代码实际上并没有尝试播放文件,直到子结束.这就是你看到计时器调用的原因.我设置了一个2秒计时器给自己一个缓冲区,这样它就可以在正确设置错误模式的情况下开始播放过程.下面是我用于计时器已用事件的代码
'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
最后一点需要注意的是.根据我的理解,这个过程禁止显示严重错误,所以要小心,在我的情况下,我无法找到由抛出的错误引起的任何特定错误或系统不稳定,所以我暂时禁用它以增加程序的可用性.我不建议每次遇到系统错误时都这样做,因为错误通常指向应该修复的程序中的缺陷/错误.此外,在我看来,您永远不需要永久关闭严重错误,这意味着确保在完成后将其重新打开.我希望这些信息可以帮助和欣赏那些回答或提出问题的人的时间和知识.
还发现您应该能够通过在WMP开始加载媒体文件之前调用Windows API函数SetErrorMode(SEM_FAILCRITICALERRORS)来抑制此错误.
所以,对于Vb来说:
'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 )
我没有对此进行过测试,请告诉我这是否有帮助.