首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

Windows 服務程式顯示互動視窗的關鍵技術

     編輯:關於VC++

核心難點

Windows 服務預設運行於非互動式工作階段,無法直接存取使用者桌面顯示視窗。要實現服務程式彈出對話框與使用者互動,必須明確開啟 WinSta0 視窗站與 Default 桌面物件。

完整實作代碼

BOOL CServiceModule::ShowMsgDlg(void)
{
    HDESK hdeskCurrent, hdesk;
    HWINSTA hwinstaCurrent, hwinsta;
    
    // 保存當前環境
    hwinstaCurrent = GetProcessWindowStation();
    hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
    
    // 開啟 WinSta0 視窗站
    hwinsta = OpenWindowStation(_T("winsta0"), FALSE,
        WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS |
        WINSTA_CREATEDESKTOP | WINSTA_ENUMDESKTOPS |
        WINSTA_ENUMERATE | WINSTA_EXITWINDOWS |
        WINSTA_READATTRIBUTES | WINSTA_READSCREEN |
        WINSTA_WRITEATTRIBUTES);
    if (!hwinsta || !SetProcessWindowStation(hwinsta)) return FALSE;
    
    // 開啟 Default 桌面
    hdesk = OpenDesktop(_T("default"), 0, FALSE,
        DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |
        DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |
        DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD |
        DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP |
        DESKTOP_WRITEOBJECTS);
    if (!hdesk || !SetThreadDesktop(hdesk)) return FALSE;
    
    // 此處已具備互動權限,可顯示對話框
    CMsgDlg dlgMsg;
    dlgMsg.DoModal();
    
    // 還原環境並清理資源
    SetProcessWindowStation(hwinstaCurrent);
    SetThreadDesktop(hdeskCurrent);
    CloseWindowStation(hwinsta);
    CloseDesktop(hdesk);
    return TRUE;
}

關鍵點解析

  • 權限完整性:OpenWindowStation 和 OpenDesktop 必須請求完整存取權限旗標,否則後續視窗操作會失敗
  • 環境切換:必須呼叫 SetProcessWindowStation 和 SetThreadDesktop 將呼叫執行緒關聯到互動式桌面
  • 資源清理:對話框關閉後務必還原原始視窗站與桌面,並關閉開啟的控制代碼,避免資源洩漏
  • 阻塞特性:使用 DoModal() 會阻塞服務執行緒,生產環境建議改用非模態視窗或獨立 UI 執行緒

編譯與測試環境

驗證環境:Windows 2000 Professional + VC6.0 + SP5 + Platform SDK 2001.8。若編譯失敗請更新至最新 Platform SDK。編譯生成 guiser.exe,以 guiser /service 註冊服務,再從控制台服務管理工具啟動即可看到對話框彈出。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved