微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Windows – .NET应用程序中的Vista异常“异常处理消息”

BackgroundI在4.0 Framework上构建了一个VB .NET应用程序,主要功能的一部分是内置的AxWMPLib.Ax WindowsMediaPlayer,它允许我们将文件路径作为URL传递给播放器,然后通过内置的媒体播放器播放.我的开发平台是Windows 7上的VS 2010 Pro.

问题我们最近开始在多个操作系统上测试这个应用程序.应用程序在多个win7机器上的Win 7上运行良好,一些用于开发其他机器.问题是我们在Vista上运行应用程序.应用程序第一次尝试在文件打开后播放它会引发错误

它大部分时间都这样做,但并非总是这样,而且我几次无法建立一个模式,它没有抛出错误.此外,它仅针对后续文件播放的第一个文件执行此操作.它避免了Try catchs的错误处理.

ResearchI对这个问题做了很多研究.我发现它似乎困扰着其他媒体播放器和网站,甚至是某些机器上的WMP.有些文章指向特定的Windows KB更新,其他文章建议运行修复磁盘来修复可能有害的dll.我已经尝试了其中许多失败,因为问题仍然存在于我必须测试的两台Vista机器上.

Codehere是发生此错误调用方法

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插件,编解码器或显示驱动程序引起的.
还发现您应该能够通过在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 )

我没有对此进行过测试,请告诉我这是否有帮助.

原文地址:https://www.jb51.cc/windows/365132.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐