2010-08-25 24 views
6

Tôi đang cố gắng đặt móc khóa cửa sổ ở mức thấp để lấy ba phím được nhấn ngay cả khi ứng dụng không được lấy nét. Để thực hiện điều này, tôi gọi SetWindowsHookEx nhưSetWindowsHookEx trả về 0 khi biên dịch khuôn khổ .NET 4.0 trong các máy 32bit

// Create an instance of HookProc. 
KeyboardHookProcedure = new HookProc(KeyboardHookProc); 
//install hook 
hKeyboardHook = SetWindowsHookEx(
    WH_KEYBOARD_LL, 
    KeyboardHookProcedure, 
    Marshal.GetHINSTANCE(
     Assembly.GetExecutingAssembly().GetModules()[0]), 
    0); 
//If SetWindowsHookEx fails. 
if (hKeyboardHook == 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 
    Stop(false, true, false); 
    //Initializes and throws a new instance of the Win32Exception class with the specified error. 
    throw new Win32Exception(errorCode); 
} 

này được sử dụng để làm việc trên 32bit và 64bit máy bằng cách sử dụng .NET Framework 3.5 nhưng sau khi nâng cấp lên .NET Framework 4.0 ngừng làm việc trên máy 32bit.

Có ai biết cách giải quyết vấn đề này để tôi có thể sử dụng Khung 4.0 và thực hiện công việc này trên cả máy 32bit và 64bit không?

+1

Trong .NET 4.0, SetWindowsHookEx trả về 0 cho tôi với một lỗi Hook Thủ tục không hợp lệ. – tofutim

Trả lời

21

import dll như thế này:

[DllImport("kernel32.dll")] 
    public static extern IntPtr GetModuleHandle(string name); 

sau đó sử dụng

GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName) 

để thay thế

Marshal.GetHINSTANCE(
    Assembly.GetExecutingAssembly().GetModules()[0] 
+1

Đã có cùng một vấn đề và giải pháp là thay đổi mã được đề xuất, sử dụng GetModuleHandle (...) để có được xử lý. – user2928227

+0

Cảm ơn bạn. Điều này làm việc hoàn hảo cho tôi. Tôi đã không nhận được mô-đun chính. Tôi đã nhận được các mô-đun hiện tại và nó đã trở về 0. –

+0

Cùng một vấn đề ở đây.Viết trình quản lý cửa sổ nhanh để tôi có thể nhấn phím, kéo hình chữ nhật trên màn hình và chụp nhanh cửa sổ. Đào lên một mô-đun "GlobalHooks" cũ tôi đã viết cách đây vài năm cho .NET 2.0, và phát hiện ra SetWindowsHookEx đã thất bại với số không. Điều này giải quyết được vấn đề. Tôi cũng tự lưu ý rằng tôi cần lặp lại tất cả các phím gọi GetAsyncKeyState, thay vì chỉ thực hiện một cuộc gọi đến GetKeyboardState, vì nó không thành công với các vấn đề luồng, như nó sẽ không nhận được trạng thái sửa đổi chính xác khi các ứng dụng khác đang ở phía trước. GetAsyncKeyState phải được sử dụng. – Triynko

1

Giải quyết nó bằng cách nhắm mục tiêu từng nền tảng riêng biệt. Cấu hình VS để biên dịch cả một phiên bản Win32 và Win64 và triển khai trên x86 và x64 máy nhị phân tương ứng của họ.

Win32 hoặc x86 chạy trên cả máy 32 bit và 64 bit.

2

Từ tài liệu cho SetWindowsHookEx

hMod [trong]
HINSTANCE
Một handle các DLL chứa thủ tục hook được trỏ đến bởi các tham số lpfn. Tham số hMod phải được đặt thành NULL nếu tham số dwThreadId chỉ định một luồng được tạo bởi quy trình hiện tại và nếu thủ tục móc nằm trong mã được liên kết với quy trình hiện tại.

Vì vậy, bạn nên đi qua trong IntPtr.Zero cho NULL

//install hook 
    hKeyboardHook = SetWindowsHookEx(
    WH_KEYBOARD_LL, 
    KeyboardHookProcedure, 
    IntPtr.Zero, 
    0); 
0

Hans Passant:

Bất kỳ mô-đun xử lý sẽ làm vì nó không thực sự có được sử dụng cho móc ở mức độ thấp, không có DLL cần phải được tiêm để làm cho họ làm việc. Một số chăm sóc trong việc chọn một là bắt buộc đối với .NET 4 vì CLR của nó không còn là xử lý giả lập mô-đun cho các hội đồng quản lý thuần túy. Một trong những tốt nhất để sử dụng là một trong những bạn nhận được từ pinvoking LoadLibrary ("user32.dll") vì nó là luôn luôn được nạp. Bạn không cần phải gọi FreeLibrary().

Bạn sẽ cần phải tuyên bố này để gọi LoadLibrary:

[DllImport("kernel32", SetLastError=true, CharSet = CharSet.Auto)] 
private static extern IntPtr LoadLibrary(string fileName); 
Các vấn đề liên quan