2014-03-02 772 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事件来订阅事件。

一个程序并没有经过真正的测试,并准备发布,直到您还测试了它可以表现的特殊方式。很难做到,经常跳过。您需要使用“假设”方案,故意抛出异常来锻炼它,这是查看您的程序是否仍能正常恢复的好方法。究竟在哪里放置这样的抛出语句是需要经验的东西,这种解决失败的方式就像这样。