加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

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

发布时间:2020-12-14 04:13:50 所属栏目:Windows 来源:网络整理
导读:我的应用程序中的某个地方(以及第三方代码库)是一个阻止 Windows的窗口过程: 退出 关闭 重新启动 我在我的代码中找到了一个位置,我在调用DefWindowProc时犯了一个非常常见的错误,但调用错误: FBroadcastListenerHwnd := AllocateHWnd(BroadcastListenerWin
我的应用程序中的某个地方(以及第三方代码库)是一个阻止 Windows的窗口过程:

>退出
>关闭
>重新启动

我在我的代码中找到了一个位置,我在调用DefWindowProc时犯了一个非常常见的错误,但调用错误:

FBroadcastListenerHwnd := AllocateHWnd(BroadcastListenerWindowProc);

procedure TGrobber.BroadcastListenerWindowProc(var msg: TMessage);
begin
   DefWindowProc(FBroadcastListenerHwnd,msg.msg,msg.wparam,msg.lparam);
end;

我修复了那个bug,而我的test program不再停止关机了.

但完整的应用程序

我现在面临着不得不撕掉一个程序,直到我的计算机终于重新启动.

在我的应用程序内部的某个地方是一个附加到HWND的Window过程,它返回零到WM_QUERYENDSESSION.如果我只知道HWND,我可以使用Spy找到Window.

但我怎么能找到那个人呢?

Windows应用程序事件日志记录了停止关闭的过程:

并且在更详细的应用程序和服务日志中有更详细的日志.但那些没有证件.

我怎样才能找到有问题的hwnd?

尝试

我尝试使用EnumThreadWindows来获取我的“主”线程的所有窗口,并想要手动向它们发送WM_QUERYENDSESSION以查看谁返回false:

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个hwnds.戳他们:

var
   window: HWND;
   res: LRESULT;

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

但没有人确实归零.

所以这是排水管的一个管.

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读