windows - 如何找到阻止关机的 HWND?

标签 windows delphi hwnd

我的应用程序中的某处(连同第 3 方代码库)是一个窗口过程,它阻止 Windows:

  • 注销
  • 关闭
  • 重新启动

我发现我的代码中有一个地方犯了一个非常常见的错误,即调用 DefWindowProc,但调用不正确:

之前:

void Grobber.BroadcastListenerWindowProc(ref TMessage msg)
{
   DefWindowProc(_broadcastListenerHwnd, msg.msg, msg.wparam, msg.lparam);
}

之后:

void Grobber.BroadcastListenerWindowProc(ref TMessage msg)
{
   //20170207: Forgetting to set the result can, for example, prevent Windows from restarting
   msg.Result = DefWindowProc(_broadcastListenerHwnd, msg.msg, msg.wparam, msg.lparam);
}

我修复了那个错误,我的 test program不再停止关机。

但是完整的应用程序可以

我现在面临着不得不将程序拆成零的问题,直到我的计算机最终重新启动。

在我的应用程序深处的某处是一个附加到 HWND 的 Window 过程,它向 WM_QUERYENDSESSION 返回零.如果我知道 HWND,我就可以使用 Spy++ 找到窗口。

但是我怎样才能找到那个hwnd呢?

Windows Application 事件日志记录了停止关机的进程:

enter image description here

在更详细的应用程序和服务日志中很可能会有更详细的日志。但这些都没有记录。

如何找到有问题的 hwnd

尝试

我尝试使用 EnumThreadWindows 获取我的“主”线程的所有窗口,我想手动发送 WM_QUERYENDSESSION 给它们,看看谁返回 错误:

var
   wnds: TList<HWND>;

function DoFindWindow(Window: HWnd; Param: LPARAM): Bool; stdcall;
var
   wnds: TList<HWND>;
begin
   wnds := TList<HWND>(Param);
   wnds.Add(Window);
   Result := True;
end;

wnds := TList<HWND>.Create;
enumProc := @DoFindWindow;
EnumThreadWindows(GetCurrentThreadId, EnumProc, LPARAM(wnds));

现在我有一个包含 12 个 hwnd 的列表。戳他们:

var
   window: HWND;
   res: LRESULT;

for window in wnds do
begin
    res := SendMessage(window, WM_QUERYENDSESSION, 0, 0);
    if res = 0 then
    begin
        ShowMessage('Window: '+IntToHex(window, 8)+' returned false to WM_QUERYENDSESSION');
    end;
end;

但是没有人返回零。

所以这是一根 pipe 下水道。

最佳答案

EnumThreadWindows 仅枚举一个特定线程的窗口。可能是有问题的窗口是在线程中创建的。因此,我建议您使用 EnumWindows 枚举应用程序中的所有顶级窗口以进行测试。

在线程中初始化 COM 就足够了,您将拥有一个您不知道的窗口。这样在线程中调用 WaitForSingleObject 可能是你的罪魁祸首: Debugging an application that would not behave with WM_QUERYENDSESSION

关于windows - 如何找到阻止关机的 HWND?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42094620/

相关文章:

python - multiprocessing.pool.imap 是否有允许多个参数的变体(如星图)?

ruby-on-rails - Windows 版 Ruby on Rails 2.0 入门

delphi - 嵌入式 PC 网络摄像头 delphi 应用程序不断弹出视频捕获对话框

c++ - GetProcessId 失败,错误 6 : The handle is invalid

python - 在 Windows 上的 Python 中获取上次更改时间

c++ - 编译问题 : LIBUSB_1 with cmake project on Windows

delphi - 我自己的存储和检索使用 Delphi 文本 DFM 格式的生命周期很长

delphi - 如何管理delphi单元中的循环引用?

c++ - Win32 在应用程序内使用资源字体