以下代码在过去的几个小时内给了我一些麻烦。 我正在尝试编写一个小程序(基于Web上的一些教程),它使用WH_JOURNALRECORD窗口挂钩来记录击键。
主要代码:
#include "StdAfx.h"
#include <tchar.h>
#include <iostream>
#include <windows.h>
using std::cout;
using std::endl;
int _tmain(int argc, _TCHAR* argv[]) {
HINSTANCE hinst = LoadLibrary(_T("testdll3.dll"));
typedef void (*Install)();
typedef void (*Uninstall)();
Install install = (Install) GetProcAddress(hinst, "install");
Uninstall uninstall = (Uninstall) GetProcAddress(hinst, "uninstall");
install();
int foo;
std::cin >> foo;
cout << "Uninstalling" << endl;
uninstall();
return 0;
}
DLL的代码:
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
HHOOK hhk;
HHOOK hhk2;
LRESULT CALLBACK journalRecordProc(int code, WPARAM wParam, LPARAM lParam) {
FILE * fileLog = fopen("journal.txt", "a+");
fprintf(fileLog,"loggedJournal\n");
fclose(fileLog);
CallNextHookEx(hhk,code,wParam,lParam);
return 0;
}
LRESULT CALLBACK wireKeyboardProc(int code,WPARAM wParam,LPARAM lParam) {
FILE * fileLog = fopen("keyboard.txt", "a+");
fprintf(fileLog,"loggedKeyboard\n");
fclose(fileLog);
CallNextHookEx(hhk,code,wParam,lParam);
return 0;
}
extern "C" __declspec(dllexport) void install() {
HINSTANCE thisDllInstance = LoadLibrary(_T("testdll3.dll"));
hhk = SetWindowsHookEx(WH_JOURNALRECORD, journalRecordProc, thisDllInstance, NULL);
hhk2 = SetWindowsHookEx(WH_KEYBOARD, wireKeyboardProc, thisDllInstance, NULL);
}
extern "C" __declspec(dllexport) void uninstall() {
UnhookWindowsHookEx(hhk);
UnhookWindowsHookEx(hhk2);
}
BOOL WINAPI DllMain( __in HINSTANCE hinstDLL, __in DWORD fdwReason, __in LPVOID lpvReserved) {
return TRUE;
}
由于某种原因,键盘钩子(SetWindowsHookEx(WH_KEYBOARD,wireKeyboardProc,..))工作(创建'keyboard.txt'文件),但是日志钩子(SetWindowsHookEx(WH_JOURNALRECORD,journalRecordProc,...))没有。也就是说,永远不会调用日记钩子的回调(永远不会创建journal.txt文件)。
我认为这可能与Windows的UAC(我在搜索网页时发现)有关,但是禁用UAC并运行具有管理权限的程序并没有帮助。
我不知道现在该怎么办。任何人都可以帮助我吗?
由于
里斯
其他信息:我正在使用Windows 7 + Visual Studio 2010
修改: 事实证明,这确实与访问权限有关。也就是说,从Windows Vista开始,出于安全原因,日志挂钩(WH_JOURNALRECORD)被禁用(另请参阅this website)。最后,我们使用了一种完全不同的方法在我们的应用程序中提供类似的功能(我在这里不会详细说明,因为我在问这个问题的1.5年后我正在编辑这个问题而且我不记得所有的我们的解决方案的详细信息)。
答案 0 :(得分:2)
WH_JOURNALRECORD与其他人不同。您不需要将其放入DLL中,但是您需要在应用程序中设置一个消息循环来处理该处理程序(在您的应用程序的上下文中)。我前段时间在另一个网站上发布了一个例子:http://forum.4programmers.net/viewtopic.php?p=557297#id557297,钩子在示例中捕获WM_MOUSEMOVE并将结果打印到控制台。
这种钩子很昂贵,因为每次调用回调都必须将执行上下文切换到你的应用程序。
答案 1 :(得分:1)
MSDN为Journal Record钩子声明了以下内容:
与大多数其他全局钩子不同 程序,JournalRecordProc和 JournalPlaybackProc挂钩程序 总是在上下文中调用 设置钩子的线程。
如果将Journal钩子的回调移动到exe,是否会导致它被调用?
另外,在LoadLibrary()
中调用GetModuleHandle()而不是install()
不是更好,因为DLL已经加载了吗?
关于UAC和管理员权限,挂钩在作为普通用户执行时可以工作。除此之外唯一的副作用是只会挂钩在该级别或更低级别运行的进程。因此,如果您的应用程序以普通用户身份运行,那么任何以普通用户身份运行的进程都将被挂钩,但那些以管理员身份运行的进程将不会被挂钩。
答案 2 :(得分:1)
时:
1.应用程序需要以管理权限运行
2.应用程序必须从(子目录)c:\ program files
运行
3.要禁用UAC对话框,必须对应用程序进行数字签名
请注意,使用UAC活动Windows(Vista及更高版本)将不允许调试exe。
或者......您可以禁用UAC(在(调试)时很有用。
这里是Visual Studio的设置对话框,将检查我是否可以获取XML格式的清单文件