2014-03-02 113 views
1

我開發了一個包含鍵盤掛鉤的程序(在此webpage中),當用戶按下某個鍵時它會播放聲音。Application1已停止工作

當我調試它,它完美的作品,但有時這種錯誤出現:

No se controló System.InvalidOperationException 
HResult=-2146233079 
Message=Error al crear el formulario. Consulte Exception.InnerException para obtener más detalles. Error: Could not set keyboard hook 
Source=CBAS 
StackTrace: 
en CBAS.My.MyProject.MyForms.Create__Instance__[T](T Instance) en 17d14f5c-a337-4978-8281-53493378c1071.vb:línea 190 
en CBAS.My.MyProject.MyForms.get_Form1() 
en CBAS.My.MyApplication.OnCreateMainForm() en C:\Users\win8\Desktop\CBAS\CBAS\My Project\Application.Designer.vb:línea 35 
en Microsoft.VisualBasic.ApplicationServices.WindowsF ormsApplicationBase.OnRun() 
en Microsoft.VisualBasic.ApplicationServices.WindowsF ormsApplicationBase.DoApplicationModel() 
en Microsoft.VisualBasic.ApplicationServices.WindowsF ormsApplicationBase.Run(String[] commandLine) 
en CBAS.My.MyApplication.Main(String[] Args) en 17d14f5c-a337-4978-8281-53493378c1071.vb:línea 81 
en System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
en System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
en Microsoft.VisualStudio.HostingProcess.HostProc.Run UsersAssembly() 
en System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
en System.Threading.ExecutionContext.RunInternal(Exec utionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
en System.Threading.ExecutionContext.Run(ExecutionCon text executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
en System.Threading.ExecutionContext.Run(ExecutionCon text executionContext, ContextCallback callback, Object state) 
en System.Threading.ThreadHelper.ThreadStart() 
InnerException: 
HResult=-2146233088 
Message=Could not set keyboard hook 
Source=CBAS 
StackTrace: 
en CBAS.KeyboardHook..ctor() en C:\Users\win8\Desktop\CBAS\CBAS\KeyboardHook.vb:lí nea 57 
en CBAS.Form1..ctor() en C:\Users\win8\Desktop\CBAS\CBAS\Form1.vb:línea 8 
InnerException:) 

但是當我發佈它,執行它,我按一個鍵,這個錯誤總是出現:

「Application1已停止工作,Windows正在收集有關此問題的更多信息...」

我不知道爲什麼。

我該如何解決?

WER(Windows錯誤報告)的文件,這將出現(它在西班牙,因爲我西班牙人)

Version=1 
EventType=CLR20r3 
EventTime=130379893951236939 
ReportType=2 
Consent=1 
UploadTime=130379893952509742 
ReportIdentifier=de74a3fd-9fc5-11e3-bf5a-2016d88a811a 
IntegratorReportIdentifier=de74a3fc-9fc5-11e3-bf5a-2016d88a811a 
WOW64=1 
NsAppName=Application1.exe 
Response.BucketId=40a1e70aa352cd3ac6cc9fb760f9bba0 
Response.BucketTable=5 
Response.LegacyBucketId=94505433654 
Response.type=4 
Response.CabId=94493168456 
Sig[0].Name=Firma del problema 01 
Sig[0].Value=application1.exe 
Sig[1].Name=Firma del problema 02 
Sig[1].Value=1.0.0.0 
Sig[2].Name=Firma del problema 03 
Sig[2].Value=530f5ce4 
Sig[3].Name=Firma del problema 04 
Sig[3].Value=System 
Sig[4].Name=Firma del problema 05 
Sig[4].Value=4.0.30319.18045 
Sig[5].Name=Firma del problema 06 
Sig[5].Value=5126f9e5 
Sig[6].Name=Firma del problema 07 
Sig[6].Value=1312 
Sig[7].Name=Firma del problema 08 
Sig[7].Value=43 
Sig[8].Name=Firma del problema 09 
Sig[8].Value=System.IO.FileNotFoundException 
DynamicSig[1].Name=Versión del sistema operativo 
DynamicSig[1].Value=6.2.9200.2.0.0.768.101 
DynamicSig[2].Name=Id. de configuración regional 
DynamicSig[2].Value=3082 
DynamicSig[22].Name=Información adicional 1 
DynamicSig[22].Value=ad52 
DynamicSig[23].Name=Información adicional 2 
DynamicSig[23].Value=ad5243c3e40479b968754b46da71fc1d 
DynamicSig[24].Name=Información adicional 3 
DynamicSig[24].Value=cb3a 
DynamicSig[25].Name=Información adicional 4 
DynamicSig[25].Value=cb3ad7e6b5724be9ade53a06384fee8d 
UI[2]=C:\Users\yo\Desktop\publish\Application Files\Application1_1_0_0_12\Application1.exe 
UI[3]=Application1 dejó de funcionar 
UI[4]=Windows puede buscar una solución en línea al problema. 
UI[5]=Buscar una solución en línea y cerrar el programa 
UI[6]=Buscar una solución en línea más tarde y cerrar el programa 
UI[7]=Cerrar el programa 
LoadedModule[0]=C:\Users\yo\Desktop\publish\Application Files\Application1_1_0_0_12\Application1.exe 
LoadedModule[1]=C:\windows\SYSTEM32\ntdll.dll 
LoadedModule[2]=C:\windows\SYSTEM32\MSCOREE.DLL 
LoadedModule[3]=C:\windows\SYSTEM32\KERNEL32.dll 
LoadedModule[4]=C:\windows\SYSTEM32\KERNELBASE.dll 
LoadedModule[5]=C:\windows\system32\apphelp.dll 
LoadedModule[6]=C:\windows\SYSTEM32\ADVAPI32.dll 
LoadedModule[7]=C:\windows\SYSTEM32\msvcrt.dll 
LoadedModule[8]=C:\windows\SYSTEM32\sechost.dll 
LoadedModule[9]=C:\windows\SYSTEM32\RPCRT4.dll 
LoadedModule[10]=C:\windows\SYSTEM32\SspiCli.dll 
LoadedModule[11]=C:\windows\SYSTEM32\CRYPTBASE.dll 
LoadedModule[12]=C:\windows\SYSTEM32\bcryptPrimitives.dll 
LoadedModule[13]=C:\Windows\Microsoft.NET\Framework\v4.0.30319\msc oreei.dll 
LoadedModule[14]=C:\windows\SYSTEM32\SHLWAPI.dll 
LoadedModule[15]=C:\windows\SYSTEM32\USER32.dll 
LoadedModule[16]=C:\windows\SYSTEM32\GDI32.dll 
LoadedModule[17]=C:\windows\system32\IMM32.DLL 
LoadedModule[18]=C:\windows\SYSTEM32\MSCTF.dll 
LoadedModule[19]=C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr .dll 
LoadedModule[20]=C:\windows\SYSTEM32\MSVCR110_CLR0400.dll 
LoadedModule[21]=C:\windows\assembly\NativeImages_v4.0.30319_32\ms corlib\391541c89ed7585fc7e8936c43cee387\mscorlib.n i.dll 
LoadedModule[22]=C:\windows\SYSTEM32\ole32.dll 
LoadedModule[23]=C:\windows\SYSTEM32\combase.dll 
LoadedModule[24]=C:\windows\system32\uxtheme.dll 
LoadedModule[25]=C:\windows\assembly\NativeImages_v4.0.30319_32\Sy stem\f0602360211041a6be208f0b4138dddd\System.ni.dl l 
LoadedModule[26]=C:\windows\assembly\NativeImages_v4.0.30319_32\Sy stem.Core\bca236f576ea12db3a9191f4586a445a\System. Core.ni.dll 
LoadedModule[27]=C:\windows\assembly\NativeImages_v4.0.30319_32\Mi crosoft.V9921e851#\544c2dc6a8eccbe94917fa495786d22 8\Microsoft.VisualBasic.ni.dll 
LoadedModule[28]=C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr jit.dll 
LoadedModule[29]=C:\windows\SYSTEM32\OLEAUT32.dll 
LoadedModule[30]=C:\windows\assembly\NativeImages_v4.0.30319_32\Sy stem.Drawing\61be23d6a688188e3419a1eb46fc9d9d\Syst em.Drawing.ni.dll 
LoadedModule[31]=C:\windows\assembly\NativeImages_v4.0.30319_32\Sy stem.Windows.Forms\11b4af16e791a6b0ada4a97d3e64e27 a\System.Windows.Forms.ni.dll 
LoadedModule[32]=C:\windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.9200.16658_none_bf1 359a245f1cd12\comctl32.dll 
LoadedModule[33]=C:\windows\SYSTEM32\dwmapi.dll 
LoadedModule[34]=C:\windows\assembly\NativeImages_v4.0.30319_32\Sy stem.Runt73a1fc9d#\3ca3214971476bd8dfa50fb1ad771f6 9\System.Runtime.Remoting.ni.dll 
LoadedModule[35]=C:\windows\WinSxS\x86_microsoft.windows.gdiplus_6 595b64144ccf1df_1.1.9200.16518_none_ba1cf6b7e09f19 18\gdiplus.dll 
LoadedModule[36]=C:\windows\SYSTEM32\DWrite.dll 
LoadedModule[37]=C:\windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.9200.16579_none_8937 eec6860750f5\comctl32.dll 
LoadedModule[38]=C:\windows\SYSTEM32\winmm.dll 
LoadedModule[39]=C:\windows\SYSTEM32\WINMMBASE.dll 
LoadedModule[40]=C:\windows\SYSTEM32\cfgmgr32.dll 
LoadedModule[41]=C:\windows\SYSTEM32\DEVOBJ.dll 
LoadedModule[42]=C:\windows\SYSTEM32\CRYPTSP.dll 
LoadedModule[43]=C:\windows\system32\rsaenh.dll 
LoadedModule[44]=C:\windows\SYSTEM32\VERSION.dll 
LoadedModule[45]=C:\Windows\Microsoft.NET\Framework\v4.0.30319\dia symreader.dll 
State[0].Key=Transport.DoneStage1 
State[0].Value=1 
File[0].CabName=WERInternalMetadata.xml 
File[0].Path=WER3909.tmp.WERInternalMetadata.xml 
File[0].Flags=851971 
File[0].Type=5 
File[0].Original.Path=C:\Users\win8\AppData\Local\temp\WE R3909.tmp.WERInternalMetadata.xml 
File[1].CabName=triagedump.dmp 
File[1].Path=WER44E2.tmp.dmp 
File[1].Flags=2949123 
File[1].Type=6 
File[1].Original.Path=C:\Users\win8\AppData\Local\temp\WE R44E2.tmp.dmp 
File[2].CabName=Report.cab 
File[2].Path=Report.cab 
File[2].Flags=196608 
File[2].Type=9 
File[2].Original.Path=Report.cab 
FriendlyEventName=Dejó de funcionar 
ConsentKey=CLR20r3 
AppName=Application1 
AppPath=C:\Users\yo\Desktop\publish\Application Files\Application1_1_0_0_12\Application1.exe 
NsPartner=windows 
NsGroup=windows8 

在Form1我有這樣的代碼:

Imports System.Threading 

Public Class Form1 
    Dim iresult As Long 
    Dim ResourceFilePathPrefix As String 
    Private Declare Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" (ByVal lpstrCommand As String, ByVal lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As Long) As Long 
    Private Declare Function mciExecute Lib "winmm.dll" (ByVal lpstrCommand As String) As Long 
    Private WithEvents kbHook As New KeyboardHook 
    Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer 

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load 
     If System.Diagnostics.Debugger.IsAttached() Then 
      ResourceFilePathPrefix = System.IO.Path.GetFullPath(Application.StartupPath & "\..\..\resources\") 
     Else 
      ResourceFilePathPrefix = Application.StartupPath & "\resources\" 
     End If 

    End Sub 
    Private Sub kbHook_KeyDown(ByVal Key As System.Windows.Forms.Keys) Handles kbHook.KeyDown 


     Select Case Key 
      Case Keys.A 
       My.Computer.Audio.Play(ResourceFilePathPrefix & "Sound1.wav") 
      Case Keys.B 
       My.Computer.Audio.Play(ResourceFilePathPrefix & "Sound2.wav") 
      Case Keys.C 
       My.Computer.Audio.Play(ResourceFilePathPrefix & "Sound3.wav") 

     End Select 
    End Sub 

End Class 

而且這是來自網絡的代碼:

Imports System.Runtime.InteropServices 

Public Class KeyboardHook 

    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _ 
    Private Overloads Shared Function SetWindowsHookEx(ByVal idHook As Integer, ByVal HookProc As KBDLLHookProc, ByVal hInstance As IntPtr, ByVal wParam As Integer) As Integer 
    End Function 
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _ 
    Private Overloads Shared Function CallNextHookEx(ByVal idHook As Integer, ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer 
    End Function 
    <DllImport("User32.dll", CharSet:=CharSet.Auto, CallingConvention:=CallingConvention.StdCall)> _ 
    Private Overloads Shared Function UnhookWindowsHookEx(ByVal idHook As Integer) As Boolean 
    End Function 

    <StructLayout(LayoutKind.Sequential)> _ 
    Private Structure KBDLLHOOKSTRUCT 
     Public vkCode As UInt32 
     Public scanCode As UInt32 
     Public flags As KBDLLHOOKSTRUCTFlags 
     Public time As UInt32 
     Public dwExtraInfo As UIntPtr 
    End Structure 

    <Flags()> _ 
    Private Enum KBDLLHOOKSTRUCTFlags As UInt32 
     LLKHF_EXTENDED = &H1 
     LLKHF_INJECTED = &H10 
     LLKHF_ALTDOWN = &H20 
     LLKHF_UP = &H80 
    End Enum 

    Public Shared Event KeyDown(ByVal Key As Keys) 
    Public Shared Event KeyUp(ByVal Key As Keys) 

    Private Const WH_KEYBOARD_LL As Integer = 13 
    Private Const HC_ACTION As Integer = 0 
    Private Const WM_KEYDOWN = &H100 
    Private Const WM_KEYUP = &H101 
    Private Const WM_SYSKEYDOWN = &H104 
    Private Const WM_SYSKEYUP = &H105 

    Private Delegate Function KBDLLHookProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer 

    Private KBDLLHookProcDelegate As KBDLLHookProc = New KBDLLHookProc(AddressOf KeyboardProc) 
    Private HHookID As IntPtr = IntPtr.Zero 

    Private Function KeyboardProc(ByVal nCode As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer 
     If (nCode = HC_ACTION) Then 
      Dim struct As KBDLLHOOKSTRUCT 
      Select Case wParam 
       Case WM_KEYDOWN, WM_SYSKEYDOWN 
        RaiseEvent KeyDown(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys)) 
       Case WM_KEYUP, WM_SYSKEYUP 
        RaiseEvent KeyUp(CType(CType(Marshal.PtrToStructure(lParam, struct.GetType()), KBDLLHOOKSTRUCT).vkCode, Keys)) 
      End Select 
     End If 
     Return CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam) 
    End Function 

    Public Sub New() 
     HHookID = SetWindowsHookEx(WH_KEYBOARD_LL, KBDLLHookProcDelegate, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly.GetModules()(0)).ToInt32, 0) 
     If HHookID = IntPtr.Zero Then 
      Throw New Exception("Could not set keyboard hook") 
     End If 
    End Sub 

    Protected Overrides Sub Finalize() 
     If Not HHookID = IntPtr.Zero Then 
      UnhookWindowsHookEx(HHookID) 
     End If 
     MyBase.Finalize() 
    End Sub 

End Class 

隨着Windbg出現這個c ODE(僅錯誤部分):

(17cc.1810): CLR exception - code e0434352 (first chance) 
(17cc.1810): Unknown exception - code c000041d (!!! second chance !!!) 
eax=0118ed58 ebx=00000005 ecx=00000005 edx=00000000 esi=0118ee24 edi=00000001 
eip=77504b32 esp=0118ed58 ebp=0118edb4 iopl=0   nv up ei pl nz ac po nc 
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b    efl=00000212 
KERNELBASE!RaiseException+0x6c: 
77504b32 8b4c2454  mov  ecx,dword ptr [esp+54h] ss:002b:0118edac=d57192f5 
*** WARNING: Unable to verify checksum for C:\windows\assembly\NativeImages_v4.0.30319_32\System\f0602360211041a6be208f0b4138dddd\System.ni.dll 
*** WARNING: Unable to verify checksum for C:\windows\assembly\NativeImages_v4.0.30319_32\Microsoft.V9921e851#\544c2dc6a8eccbe94917fa495786d228\Microsoft.VisualBasic.ni.dll 
*** WARNING: Unable to verify checksum for C:\windows\assembly\NativeImages_v4.0.30319_32\System.Windows.Forms\11b4af16e791a6b0ada4a97d3e64e27a\System.Windows.Forms.ni.dll 
0:000> gn 
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=00000002 edi=0143a8f8 
eip=77e2f6b4 esp=054af7f8 ebp=054af990 iopl=0   nv up ei pl nz na po nc 
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b    efl=00000202 
ntdll!NtWaitForWorkViaWorkerFactory+0xc: 
77e2f6b4 c21000   ret  10h 
+1

你的代碼有問題。祝你好運。 –

+0

我有什麼故障? – Frankcoding

+0

翻譯:追加所有相關的代碼。 –

回答

3

這是兩個不同的錯誤,他們的共同點是什麼草率的錯誤處理,輪流他們共同的事故變成神祕而undiagnosable崩潰。

您在網頁上找到的鍵盤掛鉤代碼對winapi錯誤的處理非常sl,,拋出一個普通的異常與「無法做到」錯誤消息。當然非常無益。通過不編寫代碼來處理設置鉤子可能失敗的可能性,情況會更糟糕,反過來又會使Form類的構造函數失敗。

SetWindowsHookEx()的DllImport聲明是borken,它缺少SetLastError屬性。要求告訴.NET,這是一個winapi函數,通過Marshal.GetLastWin32Error()報告錯誤代碼。沒有這個屬性,就無法找出函數失敗的原因。應該拋出一個System.ComponentModel.Win32Exception異常,而不是拋出異常。其中現在包含了爲什麼函數失敗的體面描述。你當然需要捕獲這個異常並顯示它,然後終止你的程序,因爲沒有理由繼續運行。使用Environment.Exit()。我不想猜測失敗的原因,只是它使用了過時的方式來傳遞模塊句柄,即第三個參數,它在.NET 4.0及更高版本上不再可靠。相反,pinvoke LoadLibrary(「user32.dll」)來獲得一個可用的模塊句柄。

第二次崩潰是一個普通的「文件未找到」異常,由Play()方法無法找到.wav文件引起。忘記複製.wav文件就足以讓你的程序崩潰。

當然,很常見的不幸事故,你永遠不會想要這樣一個簡單的事故,導致你的程序以這種不可知的方式失敗。您必須爲AppDomain.CurrentDomain.UnhandledException事件編寫一個事件處理程序,該事件記錄或顯示e.ExceptionObject。ToString()的值,然後終止你的程序。這給你一個體面的異常信息和神聖的堆棧跟蹤,告訴你程序失敗的地方和原因。使用Application.Startup事件來訂閱事件。

一個程序並沒有經過真正的測試,並準備發佈,直到您還測試了它可以表現的特殊方式。很難做到,經常跳過。您需要使用「假設」方案,故意拋出異常來鍛鍊它,這是查看您的程序是否仍能正常恢復的好方法。究竟在哪裏放置這樣的拋出語句是需要經驗的東西,這種解決失敗的方式就像這樣。