- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在尝试使用 SetWindowsHookEx
设置一个 WH_SHELL
Hook ,以获取系统范围内 HSHELL_WINDOWCREATED
和 HSHELL_WINDOWDESTROYED 的通知
事件。我为最后的 dwThreadId
参数传递了 0,根据 the docs ,应该“将 Hook 过程与所有现有线程关联起来,这些线程与调用线程在同一桌面上运行”。我还为 hMod
参数将句柄传递到我的 DLL(Delphi 中的 HInstance
),就像我查看的所有示例一样。
然而,我只收到由我自己的应用程序创建的窗口的通知,而且 - 通常情况下 - 我的测试结果是一旦我关闭我的应用程序,桌面进程就会崩溃。在您询问之前,我会调用 UnhookWindowsHookEx
。我也总是从我的处理程序中调用 CallNextHookEx
。
我正在从一个有限的用户帐户运行我的测试应用程序,但到目前为止我还没有发现任何提示表明这会发挥作用......(尽管这实际上让我感到惊讶)
AFAICT,我按照书做了所有事情(显然我没有,但到目前为止我看不出在哪里)。
我使用的是 Delphi (2007),但我认为这并不重要。
编辑:也许我之前应该提到这一点:我确实下载并尝试了几个示例(尽管不幸的是没有那么多可用于 Delphi - 尤其是 WH_SHELL
或 WH_CBT
)。虽然它们不会像我的测试应用程序那样使系统崩溃,但它们仍然不会从其他进程捕获事件(即使我可以使用 ProcessExplorer 验证它们是否正确加载到它们中)。因此,我的系统配置似乎有问题,或者示例有误,或者根本不可能从其他进程捕获事件。谁能赐教一下?
EDIT2:好的,这是我的测试项目的源代码。
包含钩子(Hook)程序的DLL:
library HookHelper;
uses
Windows;
{$R *.res}
type
THookCallback = procedure(ACode, AWParam, ALParam: Integer); stdcall;
var
WndHookCallback: THookCallback;
Hook: HHook;
function HookProc(ACode, AWParam, ALParam: Integer): Integer; stdcall;
begin
Result := CallNextHookEx(Hook, ACode, AWParam, ALParam);
if ACode < 0 then Exit;
try
if Assigned(WndHookCallback)
// and (ACode in [HSHELL_WINDOWCREATED, HSHELL_WINDOWDESTROYED]) then
and (ACode in [HCBT_CREATEWND, HCBT_DESTROYWND]) then
WndHookCallback(ACode, AWParam, ALParam);
except
// plop!
end;
end;
procedure InitHook(ACallback: THookCallback); register;
begin
// Hook := SetWindowsHookEx(WH_SHELL, @HookProc, HInstance, 0);
Hook := SetWindowsHookEx(WH_CBT, @HookProc, HInstance, 0);
if Hook = 0 then
begin
// ShowMessage(SysErrorMessage(GetLastError));
end
else
begin
WndHookCallback := ACallback;
end;
end;
procedure UninitHook; register;
begin
if Hook <> 0 then
UnhookWindowsHookEx(Hook);
WndHookCallback := nil;
end;
exports
InitHook,
UninitHook;
begin
end.
以及使用钩子(Hook)的应用程序的主要形式:
unit MainFo;
interface
uses
Windows, SysUtils, Forms, Dialogs, Classes, Controls, Buttons, StdCtrls;
type
THookTest_Fo = class(TForm)
Hook_Btn: TSpeedButton;
Output_Lbx: TListBox;
Test_Btn: TButton;
procedure Hook_BtnClick(Sender: TObject);
procedure Test_BtnClick(Sender: TObject);
public
destructor Destroy; override;
end;
var
HookTest_Fo: THookTest_Fo;
implementation
{$R *.dfm}
type
THookCallback = procedure(ACode, AWParam, ALParam: Integer); stdcall;
procedure InitHook(const ACallback: THookCallback); register; external 'HookHelper.dll';
procedure UninitHook; register; external 'HookHelper.dll';
procedure HookCallback(ACode, AWParam, ALParam: Integer); stdcall;
begin
if Assigned(HookTest_Fo) then
case ACode of
// HSHELL_WINDOWCREATED:
HCBT_CREATEWND:
HookTest_Fo.Output_Lbx.Items.Add('created handle #' + IntToStr(AWParam));
// HSHELL_WINDOWDESTROYED:
HCBT_DESTROYWND:
HookTest_Fo.Output_Lbx.Items.Add('destroyed handle #' + IntToStr(AWParam));
else
HookTest_Fo.Output_Lbx.Items.Add(Format('code: %d, WParam: $%x, LParam: $%x', [ACode, AWParam, ALParam]));
end;
end;
procedure THookTest_Fo.Test_BtnClick(Sender: TObject);
begin
ShowMessage('Boo!');
end;
destructor THookTest_Fo.Destroy;
begin
UninitHook; // just to make sure
inherited;
end;
procedure THookTest_Fo.Hook_BtnClick(Sender: TObject);
begin
if Hook_Btn.Down then
InitHook(HookCallback)
else
UninitHook;
end;
end.
最佳答案
问题是你的钩子(Hook) DLL 实际上被加载到几个不同的地址空间。任何时候 Windows 在某些外部进程中检测到必须由您的 Hook 处理的事件时,它都会将 Hook DLL 加载到该进程中(当然,如果它尚未加载的话)。
但是,每个进程都有自己的地址空间。这意味着您在 InitHook() 中传递的回调函数指针仅在您的 EXE 上下文中有意义(这就是它适用于您应用程序中的事件的原因)。在任何其他进程中,指针都是垃圾;它可能指向无效的内存位置或(更糟)指向某个随机代码部分。结果可能是访问冲突或静默内存损坏。
通常,解决方案是使用某种 interprocess communication (IPC) 以正确通知您的 EXE。对于您的情况,最轻松的方法是发布一条消息并将所需的信息(事件和 HWND)塞入其 WPARAM/LPARAM 中。您可以使用 WM_APP+n 或使用 RegisterWindowMessage() 创建一个。确保消息已发布但未发送,以避免任何死锁。
关于windows - 我必须做什么才能使我的 WH_SHELL 或 WH_CBT Hook 过程从其他进程接收事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/299370/
我创建了一个简单的钩子(Hook),我安装了它 SetWindowsHookEx(WH_CBT, addr, dll, 0); 完成后,我卸载 UnhookWindowsHookEx(0); 然后我可
我正在使用 React Hooks,当我用 mobx 的观察者包装我的组件时,我收到了这个错误。可能是什么问题?是否可以将 mobx 与 React Hooks 一起使用? import classn
我知道这个问题已经被回答过很多次了。我只是找不到解决我的问题的答案,让我相信,我要么是愚蠢的,要么是我的问题没有被解决,因为它比我更愚蠢。除此之外,这是我的问题: 我正在尝试创建一个功能组件,它从 r
我正在使用 React Navigation 的 useNavigation 钩子(Hook): 在 MyComponent.js 中: import { useNavigation } from "
我想在 gitlab 中使用预提交钩子(Hook)。我做的一切都像文档中一样:https://docs.gitlab.com/ce/administration/custom_hooks.html 在
我最近在和一些人谈论我正在编写的程序时听到了“hook”这个词。尽管我从对话中推断出钩子(Hook)是一种函数,但我不确定这个术语到底意味着什么。我搜索了定义,但找不到好的答案。有人可以让我了解这个术
我正在寻找一个在页面创建或页面更改后调用的钩子(Hook),例如“在导航中隐藏页面”、“停用页面”或“移动/删除页面“ 有人知道吗? 谢谢! 最佳答案 这些 Hook 位于 t3lib/class.t
我正在使用钩子(Hook)将新方法添加到 CalEventLocalServiceImpl 中... 我的代码是.. public class MyCalendarLocalServiceImpl e
编译器将所有 SCSS 文件编译为 STANDALONE(无 Rails)项目中的 CSS 后,我需要一个 Compass Hook 。 除了编辑“compiler.rb”(这不是好的解决方案,因为
我“.get”一个请求并像这样处理响应: resp = requests.get('url') resp = resp.text .. # do stuff with resp 阅读包的文档后,我看到
我们想在外部数据库中存储一些关于提交的元信息。在克隆或 checkout 期间,应引用此数据库,我们将元信息复制到克隆的存储库中的文件中。需要数据库而不是仅仅使用文件是为了索引和搜索等...... 我
我有一个 react 钩子(Hook)useDbReadTable,用于从接受tablename和query初始数据的数据库读取数据。它返回一个对象,除了数据库中的数据之外,还包含 isLoading
在下面的代码中,当我调用 _toggleSearch 时,我同时更新 2 个钩子(Hook)。 toggleSearchIsVisible 是一个简单的 bool 值,但是,setActiveFilt
问题 我想在可由用户添加的表单中实现输入字段的键/值对。 参见 animated gif on dynamic fields . 此外,我想在用户提交表单并再次显示页面时显示保存的数据。 参见 ani
当状态处于 Hook 状态时,它可能会变得陈旧并泄漏内存: function App() { const [greeting, setGreeting] = useState("hello");
const shouldHide = useHideOnScroll(); return shouldHide ? null : something useHideOnScroll 行为应该返回更新后
我正在使用 React-native,在其中,我有一个名为 useUser 的自定义 Hook,它使用 Auth.getUserInfro 方法从 AWS Amplify 获取用户信息,并且然后获取返
我正在添加一个 gitolite 更新 Hook 作为 VREF,并且想知道是否有办法将它应用于除 gitolite-admin 之外的所有存储库。 有一个更简单的方法而不是列出我想要应用 Hook
如何使用带有 react-apollo-hooks 的 2 个 graphql 查询,其中第二个查询取决于从第一个查询中检索到的参数? 我尝试使用如下所示的 2 个查询: const [o, setO
我是 hooks 的新手,到目前为止印象还不错,但是,如果我尝试在函数内部使用 hooks,它似乎会提示(无效的 hook 调用。Hooks can only be called inside o
我是一名优秀的程序员,十分优秀!