2014-03-02 3 views
1

키보드 훅 (this is in this 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가 문제에 대한 자세한 정보를 수집하고 있습니다 ..."

이유가 무엇인지 알 수 없습니다.

어떻게 해결할 수 있습니까?

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 

그리고 다음 WER (Windows 오류보고) 파일에서

, 이것은이 코드를 Form1에에서

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 

(I 스페인이기 때문에 그것은 스페인어의) 표시 웹의 코드입니다.

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 송시 (만 오류 부분) :

(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 오류를 매우 조잡하게 처리하여 "할 수 없습니다"오류 메시지와 함께 일반 예외를 던집니다. 물론 도움이되지 않습니다. 후크 설정이 실패 할 수있는 가능성을 다루는 코드를 작성하지 않음으로써 더 악화되었습니다. 그러면 Form 클래스의 생성자가 실패하게됩니다.

SetWindowsHookEx()에 대한 DllImport 선언은 borken이며 SetLastError 속성이 없습니다. .NET에 Marshal.GetLastWin32Error()를 통해 오류 코드를보고하는 winapi 함수임을 알리는 데 필요합니다. 이 속성이 없으면 함수가 실패한 이유를 찾을 방법이 없습니다. Exception을 throw하는 대신 System.ComponentModel.Win32Exception을 throw해야합니다. 이제는 함수가 실패한 이유에 대한 적절한 설명이 포함되어 있습니다. 물론이 예외를 잡아서 표시해야하고, 계속 실행할 이유가 없으므로 프로그램을 종료해야합니다. Environment.Exit()를 사용하십시오. 나는 그 실패 이유를 추측하고 싶지 않다. 다만, .NET 4.0 이상에서는 더 이상 신뢰할 수없는 모듈 핸들 인 3 번째 인자를 넘겨주는 오래된 방법을 사용한다는 것만 제외하면. 대신 LoadLibrary ("user32.dll")를 사용하여 사용 가능한 모듈 핸들을 가져옵니다.

두 번째 크래시는 Play() 메서드가 .wav 파일을 찾을 수 없기 때문에 발생하는 일반적인 "파일을 찾을 수 없음"예외입니다. .wav 파일을 복사하는 것을 잊어 버리는 것만으로도 프로그램이 충돌 할 수 있습니다.

물론 흔한 사고는 결코 그러한 평범한 사고로 인해 프로그램이 그렇게 놀라운 방법으로 실패하지 않게하려는 것입니다. e.ExceptionObject를 기록하거나 표시하는 AppDomain.CurrentDomain.UnhandledException 이벤트에 대한 이벤트 처리기를 작성해야합니다.ToString() 값을 입력 한 다음 프로그램을 종료하십시오. 그게 괜찮은 예외 메시지와 거룩한 스택 추적을 제공하여 프로그램이 어디서 왜 실패했는지 보여줍니다. Application.Startup 이벤트를 사용하여 이벤트를 구독하십시오.

프로그램은 실제로 테스트 할 수있는 예외적 인 방법을 테스트 할 때까지 테스트를 마친 상태입니다. 할 수없고 종종 건너 뜁니다. "what if"시나리오를 사용해야하며 의도적으로 예외를 던져서 프로그램을 정상적으로 복구 할 수 있는지 확인할 수있는 좋은 방법입니다. 이러한 throw 문을 어디에 두어야하는지 정확하게 경험할 필요가 있습니다.이 문제는 실패 문제를 해결하여 얻을 수 있습니다.

관련 문제