互動式服務

一般而言,服務是專為在沒有圖形化使用者介面的情況下自動執行的主控台應用程式, (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函式來顯示訊息方塊。 建議顯示簡單的狀態訊息。 除非您從個別執行緒呼叫 MessageBox,否則請勿在服務初始化期間或從 HandlerEx常式呼叫MessageBox,以便及時返回 SCM。

使用互動式服務

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

警告

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

 

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

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

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

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

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,所以請勿將服務設定為在終端機服務下或支援快速使用者切換的系統上執行, (使用終端機服務) 實作快速使用者切換。