2008-11-06 32 views
41

我寫了一個Windows服務,允許我遠程運行和停止應用程序。這些應用程序使用CreateProcess運行,這對我來說很有用,因爲它們大多數只執行後端處理。最近,我需要運行向當前登錄用戶呈現GUI的應用程序。如何在C++中編寫代碼以允許我的服務找到當前活動的桌面並在其上運行GUI?Windows服務如何執行GUI應用程序?

+0

你定位的是哪個版本的Windows?對於Vista和7,Windows服務不能擁有GUI組件。我的研究是從幾年前,但與該服務在運行隱藏/禁用的管理員帳戶(會話0)。當時我的解決方案是使用MSMQ服務和單獨的GUI應用程序之間的通信。 – gooch 2010-11-17 21:09:03

回答

49

羅傑Lipscombe的答案,使用WTSEnumerateSessions找到合適的桌面,然後CreateProcessAsUser啓動應用程序,桌面(你通過它的桌面的句柄作爲STARTUPINFO結構的一部分)上是正確的。

但是,我會強烈建議不要這樣做。在一些環境中,比如終端服務器主機上有許多活躍用戶,確定哪個桌面是「活動」桌面並不容易,甚至可能無法實現。

但最重要的是,如果一個應用程序突然出現在用戶的桌面上,這可能發生在一個糟糕的時間(或者是因爲用戶根本沒有料到它,或者是因爲你試圖啓動應用程序當會話尚未完全初始化時,在關閉的過程中,或其他)。

更傳統的方法是在全球啓動組中爲您的服務放置一個小型客戶端應用程序的快捷方式。此應用隨後將隨每個用戶會話一起啓動,並可用於啓動其他應用(如果需要的話),而不需要任何用戶憑證,會話和/或桌面的雜耍。

而且,這個快捷鍵可以根據需要移動由管理員/禁用的,這將使您的應用程序部署要容易得多,因爲它不會從其他Windows應用程序中使用的標準偏差...

+0

但它將不得不採取用戶憑據,對吧? – Prakash 2012-09-29 13:52:49

6

WTSEnumerateSessions和CreateProcessAsUser。

0

我想只要你只有一個用戶登錄,它就會自動顯示在該用戶的桌面上。

無論如何,有一個服務啓動exe時要非常小心。

如果對exe文件夾的寫入訪問權限不受限制,任何用戶都可以用任何其他程序替換該exe文件,然後使用系統權限運行該程序。以cmd.exe爲例(所有Windows系統都可用)。下一次該服務嘗試啓動您的exe文件,您會得到一個具有系統權限的命令外殼...

0

如果從服務啓動GUI,它將顯示在當前活動的桌面上。

但是,只有當您調整了服務權限時:您需要允許它爲interact with the desktop

1

在Win2K,XP和Win2K3中,控制檯用戶在會話0中登錄,這是服務所在的會話。如果服務配置爲交互式,它將能夠在用戶的桌面上顯示用戶界面。

但是,在Vista上,用戶無法在會話0中登錄。從服務中顯示UI有點棘手。您需要使用WTSEnumerateSessions API來枚舉活動會話,找到控制檯會話並以該用戶身份創建該進程。當然,您還需要一個令牌或用戶憑證才能做到這一點。你可以閱讀關於這個過程的更多細節here

+0

你說的這個「這個」是什麼?我在會話0是唯一的理由是,這是不使用的第一屆會議時,我登錄... – SamB 2010-11-28 23:18:36

5

有幾個人建議使用WTSEnumerateSessions和CreateProcessAsUser。我想知道爲什麼沒有人建議WTSGetActiveConsoleSessionId,因爲你說你只想定位一個登錄用戶。

幾個人肯定是正確的,雖然建議CreateProcessAsUser。如果按照您所說的方式調用普通的舊CreateProcess,那麼應用程序的GUI將以您的服務的特權而不是用戶的特權運行。

16

簡短的回答是「你不會」,因爲打開在另一個用戶上下文中運行的GUI程序通常被稱爲一個Shatter Attack一個安全漏洞。

看看這個MSDN文章在:Interactive Services。它提供了一些服務與用戶交互的選項。

總之你有以下選擇:

  • 顯示一個對話框,使用WTSSendMessage功能的用戶的會話。

  • 創建一個單獨的隱藏的GUI應用程序,並使用CreateProcessAsUser函數來運行交互式用戶的上下文內的應用程序。設計GUI應用程序以通過進程間通信(IPC)的某種方法與服務進行通信,例如命名管道。該服務與GUI應用程序通信以告訴它何時顯示GUI。應用程序將用戶交互的結果傳回服務,以便服務可以採取適當的措施。請注意,IPC可以通過網絡公開您的服務接口,除非您使用適當的訪問控制列表(ACL)。

    如果此服務在多用戶系統上運行,請將該應用程序添加到以下注冊表項,以便它在每個會話中運行:HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Run。如果應用程序對IPC使用命名管道,則服務器可以根據會話ID爲每個管道指定一個唯一名稱,從而區分多個用戶進程。

相關問題