共用方式為


互動式服務

一般而言,服務是一種控制台應用程式,其設計目的是要自動執行,而不需要圖形用戶介面(GUI)。 不過,某些服務可能需要偶爾與用戶互動。 此頁面討論如何從服務與用戶互動。

重要

從 Windows Vista 起,服務無法直接與用戶互動。 因此,使用互動式服務一節中所述的技術不應該用於新的程序代碼。

 

間接與服務的用戶互動

您可以使用下列技術,從所有支援的 Windows 版本上的服務與使用者互動:

  • 使用 WTSSendMessage 函式,在使用者的會話中顯示對話方塊。

  • 建立個別的隱藏 GUI 應用程式,並使用 CreateProcessAsUser 函式,在互動式使用者的內容中執行應用程式。 設計 GUI 應用程式,以透過一些進程間通訊 (IPC) 方法來與服務通訊,例如命名管道。 服務會與 GUI 應用程式通訊,以告知其何時顯示 GUI。 應用程式會將使用者互動的結果傳回服務,讓服務可以採取適當的動作。 請注意,除非您使用適當的訪問控制清單(ACL),否則 IPC 可以透過網路公開您的服務介面。

    如果此服務在多使用者系統上執行,請將應用程式新增至下列金鑰,以便在每個工作階段中執行:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run。 如果應用程式使用 IPC 的命名管道,伺服器就可以根據會話識別碼為每個管道提供唯一的名稱,以區分多個用戶進程。

下列技術也適用於 Windows Server 2003 和 Windows XP:

  • 使用 MB_SERVICE_NOTIFICATION呼叫 MessageBox 函式來顯示消息框。 建議用來顯示簡單狀態消息。 請勿在服務初始化期間或從 HandlerEx 例程呼叫 MessageBox,除非您從個別線程呼叫它,以便及時返回 SCM。

使用互動式服務

根據預設,服務會使用非互動式 視窗月臺,且無法與用戶互動。 不過,互動式服務 可以顯示使用者介面並接收用戶輸入。

謹慎

在提升許可權的安全性內容中執行的服務,例如 LocalSystem 帳戶,不應該在互動式桌面上建立視窗,因為任何其他在互動式桌面上執行的應用程式都可以與此視窗互動。 這會將服務公開給登入使用者執行的任何應用程式。 此外,以 LocalSystem 身分執行的服務不應該呼叫 OpenWindowStationGetThreadDesktop 函式來存取互動式桌面。

 

若要建立互動式服務,請在呼叫 CreateService 函式時執行下列動作:

  1. lpServiceStartName 參數指定 NULL,以在 LocalSystem 帳戶的內容中執行服務
  2. 指定 SERVICE_INTERACTIVE_PROCESS 旗標。

若要判斷服務是否以互動式服務的形式執行,請呼叫 GetProcessWindowStation 函式來擷取視窗月臺的句柄,以及 GetUserObjectInformation 函式,以測試視窗月臺是否具有 WSF_VISIBLE 屬性。

不過,請注意,下列登錄機碼包含值,NoInteractiveServices,可控制SERVICE_INTERACTIVE_PROCESS的效果:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows

NoInteractiveServices 值預設值為 1,這表示不論服務是否具有 SERVICE_INTERACTIVE_PROCESS,都不允許以互動方式執行。 當 NoInteractiveServices 設為 0 時,允許以互動方式執行具有 SERVICE_INTERACTIVE_PROCESS 的服務。

Windows 7、Windows Server 2008 R2、Windows XP 和 Windows Server 2003:NoInteractiveServices 值預設值為 0,這表示允許具有 SERVICE_INTERACTIVE_PROCESS 的服務以互動方式執行。 當 NoInteractiveServices 設定為非零值時,不論它是否有 SERVICE_INTERACTIVE_PROCESS,之後就不允許啟動任何服務以互動方式執行。

重要

所有服務都會在終端機服務會話 0 中執行。 因此,如果互動式服務顯示使用者介面,則只有連線到會話 0 的使用者才能看到該介面。 由於無法保證互動式使用者已連線到會話 0,因此請勿將服務設定為在終端機服務下執行為互動式服務,或在支援快速使用者切換的系統上執行(使用終端機服務實作快速使用者切換)。