背景
我已經在4.0 Framework上構建了一個VB .NET應用程序,主要功能的一部分是構建在AxWMPLib.AxWindowsMediaPlayer中,它允許我們傳遞一個文件路徑作爲播放器的URL,然後通過內置的媒體播放器播放。我的開發平臺是Windows 7上的VS 2010 Pro。問題
我們最近已經開始在多個操作系統上測試此應用程序。該應用程序在多個win7機器上的Win 7上運行良好,有些用於其他開發。問題是我們在Vista上運行應用程序。在第一次應用程序嘗試已被打開後,它會拋出一個錯誤播放文件它做到這一點大部分時間,但並非總是如此,我一直無法建立它幾次沒有拋出錯誤的模式。此外,它只對第一個播放的文件執行此操作,而不是後續文件。而且它避免了嘗試捕獲錯誤處理。
研究
我對這個問題做了很多研究。我發現它似乎困擾其他媒體播放器和網站,甚至在某些機器上播放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
,您會看到另外const的變量命名SEM_FAILCRITICALERRORS的,這是必要的變量的值設置爲1,在這種情況下,變量的名稱是非常特殊的,因爲它標誌匹配變種SetErrorMode方法中的名稱設置爲true時,此標誌禁用顯示CriticalErrors。我還將.dll分機添加到了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機器上將調試模式設置爲調試模式,逐行執行代碼。我發現代碼實際上並沒有嘗試播放文件,直到子結束。這就是您看到計時器呼叫的原因。我設置了一個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
我會爲此付出最後一次警告。根據我的理解,此過程禁止顯示嚴重錯誤,因此請小心,在我的情況下,我無法找到由拋出的錯誤導致的任何特定錯誤或系統不穩定,因此我暫時禁用此功能以增加程序的可用性。我不建議在每次出現系統錯誤時都這樣做,因爲錯誤指向程序中應該修復的缺陷/錯誤。另外,在我看來,你永遠不需要永久關閉嚴重錯誤,也就是說,當你完成之後,確保你將它們重新開啓。我希望這些信息能夠幫助和了解那些回答或投票表決問題的人的時間和知識。
+1表示您的研究=) – 2012-04-05 19:28:38
只是要確定:你是說這個Try/Catch確實不*捕獲異常? – egrunin 2012-04-05 19:32:49
正確,這個錯誤獨立於我的try/catch而發生。 – Madullah 2012-04-05 19:35:05