2013-07-27 21 views
13

Bir projede Gma.UserActivityMonitor kütüphanesini kullanmaya çalışıyorum ve kendim üstesinden gelememem bir hatayla karşılaştım.Gma.UserActivityMonitor & SetWindowsHookEx 126

var asm = Assembly.GetExecutingAssembly().GetModules()[0]; 
var mar = Marshal.GetHINSTANCE(asm); 
s_MouseHookHandle = SetWindowsHookEx(
    WH_MOUSE_LL, 
    s_MouseDelegate, 
    mar, 
    0); 
//If SetWindowsHookEx fails. 
if (s_MouseHookHandle == 0) 
{ 
    //Returns the error code returned by the last unmanaged function called using platform invoke that has the DllImportAttribute.SetLastError flag set. 
    int errorCode = Marshal.GetLastWin32Error(); 
    //do cleanup 

    //Initializes and throws a new instance of the Win32Exception class with the specified error. 
    throw new Win32Exception(errorCode); 
} 

SetWindowsHookEx hep 0 döner ve yukarıdaki kod mesajında ​​The specified module could not be found ve çağrıyla istisna atıp duruyor: HookManager.Callbacks.cs dosyasında

aşağıdaki kodla (daha fazla veya daha az) ile statik olarak adlandırılan yöntem EnsureSubscribedToGlobalMouseEvents var Marshal.GetLastWin32Error, 126 kodunu döndürür. Gma.UserActivityMonitor'un orijinal projesiyle sağlanan demoyu başarılı bir şekilde çalıştırabilirim ancak projem burada açıklamak için biraz karmaşık olduğundan, benimkiyle aradaki farkı açıklayamam. Sadece birisinin sorunu tahmin etmesini beklemesini umuyorum.

BTW, projenin SSS kısmında, Enable Visual Studio hosting process yalnızca proje hata ayıklaması olduğunda işaretlendiğinde başkalarının benimki (SetWindowsHookEx döndürme hatasıyla) sorunu olduğunu söyledi. Bu yüzden benim o kutudaki işareti kaldırdım ve hala aynı sorunu yaşıyorum ve sadece hata ayıklama modunda değil, Windows Gezgini'nde (Visual Studio dahil) yayımlama dosyasını çift tıklattığımda da.

Daha fazla bilgi vermek için, demo projesinde (hangisi iyi çalışıyor) asm değişken noktaları {Gma.UserActivityMonitor.dll} ve projemde istisna atılanla aynı!

+0

ilgili süreçlerin bitkinliğiyle ilgili olabilir ... – Yahia

+0

Lütfen daha fazla bilgi açıklayabilir misiniz, yoksa doğru kaynağa yönlendirebilir misiniz? – Mehran

+0

Hooking, genellikle, bazı kodların hedef işlemlerin bir parçası haline gelmesini içerir. Bu, farklı şekillerde başarılabilir, ancak temel olarak işleminizle ilgili bitlikteki herhangi bir farklılık, çengelli süreç (ler) ve işletim sistemi problemlere ve/veya hatalı davranışlara yol açabilir. – Yahia

cevap

27

Bu tür bir kod artık .NET 4 ve üstü üzerinde çalışmıyor. Aldığınız hata kodu başka türlü tanımlayıcı, 126 = "Belirtilen modül bulunamadı". Hangi "mar" değişkeni önemsiz içerdiğini söyler.

.NET 4 oldukça önemli bir CLR değişikliğine sahipti, artık jur kodunun yönetilmeyen modüller içinde yaşadığını iddia ediyor. Yani Marshal.GetHINSTANCE() artık çalışmıyor. Kod daha sonra özensizleşir, dönüş değerini kontrol etmeyi unutur, (IntPtr) -1'in test edilmesi başarısızlık ve felaket bildirmek için gereklidir. Codeproject'te bulduğunuz kod için oldukça yaygın, katkıda bulunanlar tarafından çözülemeyen birçok hata ve sloppiness. SO modeli değil

SetWindowsHookEx(), düşük düzeydeki kancalar için biraz garip. Geçerli bir modül tanıtıcısı gerektirir ve denetler, ancak aslında kullanmaz. Bu Windows, Win7 SP1 etrafında bir yerde sabitlendi. Kesinlikle yararlı bir düzeltme olması amaçlanmış olsa da, aslında sorunu daha da kötüleştirdi. Çünkü şimdi sizin dev makinenizde çalışabilir, ancak kullanıcı makinenizde çalışmayabilir.

Anyhoo, düzeltme basittir, sadece geçerli bir modül tanıtıcısını öksürmeniz gerekiyor. Hep yönetilen bir uygulama mevcut bir modülden tane alabilirsiniz, bunu elde etmek pinvoke LoadLibrary gerekir: Programınız zaten sona kadar

var mar = LoadLibrary("user32.dll"); 
s_MouseHookHandle = SetWindowsHookEx(
    WH_MOUSE_LL, 
    s_MouseDelegate, 
    mar, 
    0); 

FreeLibrary'i() aramaya gerek yok, o modül yüklü kalır .

+0

Teşekkürler Hans, mükemmel çalıştı. Sadece sorunu bulmayı başardığımı eklemek istiyorum. Senin kullanacağım çözüm senin olacak ama ben sadece yeni keşifler hakkında düşüncelerinizi sormak istedim. Sorun, benim işletim sistemim Windows 7x64 iken, projemin 'Platform hedefinin 'x86'ya ayarlanmasıydı. 'X64' ve 'Any CPU' gibi diğer seçenekler benim makinemde çalışıyor ancak çözümünüz 'Platform hedefi' ne bakılmaksızın çalışıyor, bu yüzden ben de çözümümde C++ ile yazılmış Win32 projeleri var. Çözümünüzün WindowsXP, Vista veya Windows 8 gibi diğer işletim sistemlerinde bile sağlam olduğunu mu düşünüyorsunuz? – Mehran

+0

Açıkçası, herhangi bir Windows sürümünde çalışmasını sağlayan cevapta işaret ettim. –

+0

Üzgünüz bunu kaçırdım. Çok teşekkür ederim. – Mehran

İlgili konular