首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 發送 WM_CLOSE 關閉 360 瀏覽器失效的排查與替代方案

     編輯:程式設計綜合問答

現象

使用 CreateProcess 啟動 360 瀏覽器,嘗試通過 EnumWindows 找到主窗口並 PostMessage(hwnd, WM_CLOSE, 0, 0) 關閉,但瀏覽器無反應。

原因分析

  1. 句柄錯誤:EnumWindows 遍歷到的可能是子窗口(如渲染進程窗口),而非主窗口。360 瀏覽器多進程架構,主窗口隸屬於 Browser 進程。
  2. 權限隔離:若調用進程完整性級別低於瀏覽器進程,PostMessage 會被 UIPI 阻攔。
  3. 消息處理:瀏覽器可能攔截 WM_CLOSE 並最小化到托盤而非退出。

排查步驟

  1. 用 Spy++ 確認目標窗口的類名、標題、進程 ID,驗證 GetWindowThreadProcessId 邏輯。
  2. 嘗試發送 WM_SYSCOMMAND, SC_CLOSE 模擬點擊關閉按鈕。
  3. 嘗試 SendMessageTimeout 配合 SMTO_ABORTIFHUNG 避免死鎖。

更穩健的替代方案

  • UI Automation:使用 IUIAutomation 尋找「關閉」按鈕並 InvokePattern 點擊,繞過消息層。
  • 命令行參數:若瀏覽器支援 --close-window 等參數,直接 CreateProcess 帶參數啟動。
  • 終止進程:最後手段 TerminateProcess,但會導致數據丟失、會話未正常保存。

代碼片段:UI Automation 關閉

#include 
// ... 初始化 COM、獲取 IUIAutomation ...
IUIAutomationElement* root;
automation->GetRootElement(&root);
IUIAutomationCondition* cond;
automation->CreatePropertyCondition(UIA_NamePropertyId, SysAllocString(L"關閉"), &cond);
IUIAutomationElement* closeBtn;
root->FindFirst(TreeScope_Subtree, cond, &closeBtn);
IInvokeProvider* invoke;
closeBtn->GetCurrentPattern(UIA_InvokePatternId, (IUnknown**)&invoke);
invoke->Invoke();
// 釋放介面...
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved