2010-08-26 103 views
1

請讓我知道如何在服務中以當前登錄用戶的身份運行應用程序。從Windows服務啓動winform應用程序

爲了給你提供背景,我有一個VB.NET Windows服務,它的唯一功能是在指定的時間運行一個Winform應用程序。除此之外,它還設置了一個系統喚醒定時器,以便系統可以在指定的時間被喚醒,如果它進入待機/睡眠狀態以運行應用程序。該服務必須滿足我們網絡上的XP/Vista/Win7桌面。此服務不會在服務器和筆記本電腦上運行。

Winform應用程序顯示用戶界面,用於提供一些輸入。如果用戶在15分鐘內未提供輸入,則默認值,然後進入系統托盤圖標。用戶可以點擊圖標並稍後更改值(在指定的時間範圍內並且也只有兩次)。

除了啓動應用程序的服務之外,服務和winform應用程序之間完全沒有交互。它還監視應用程序是否已被用戶殺死/墜毀。如果它已被殺死/墜毀,則在前一次運行30分鐘後運行一個新實例。

如果沒有用戶登錄,那麼我也希望應用程序在指定的時間運行。正如我之前所說,該應用程序有一個默認計時器。因此,如果某個用戶剛從系統註銷,則默認值將由winform應用程序設置。

現在來談談爲什麼我堅持使用此設計 - 我無法使用TaskScheduler,因爲它已在所有機器上禁用,並且安全團隊不願意更改它。 TaskScheduler可以選擇將機器從睡眠和其他事物中喚醒。所以基本上我最終創建了一個類似於任務調度程序的服務。

當前當我通過process.start()在服務中運行app.exe時,它在SYSTEM帳戶下作爲服務運行也在LOCAL SYSTEM下運行。所以基本上我沒有得到任何用戶界面。無論如何在當前登錄的用戶下運行它?我不擔心多用戶登錄,因爲我們不會在服務器上運行它,並且我們的桌面上未啓用切換用戶。即使有人通過mstsc進行了遠程登錄,我也需要運行應用程序並向用戶顯示UI。

請讓我知道如何在服務中以當前登錄用戶的身份運行應用程序。

感謝 askids

回答

1

有報道說,我發佈了一些補充意見。但不知何故,我無法看到它:(

現在回到原來的問題,我可以幾個試錯後,看着辦吧。我會把它的細節。

在Vista及以上,服務運行從其他用戶會話隔離。他們會運行1 0運行用戶會話及以上。所以基本上你需要模擬登錄的用戶的過程電流。

  1. 使用WTSEnumerateSessions和 GET會議。檢查會話 狀態是否處於活動狀態。將當前登錄的用戶會話爲 。如果 沒有活動會話,則表示 表示沒有登錄用戶。在我的情況下,在 我的情況下,用戶只會記錄1個登錄 。所以我不需要弄清楚 的活動會話(像其他人可能需要做的 )。
  2. 使用WTSQueryUserToken在活動會話中獲取用戶令牌。 創建使用DuplicateTokenEx
  3. 主要用戶令牌使用CreateEnvironmentBlock
  4. 使用上面的CreateProcessAsUser

爲什麼它在XP的工作,而不是在Vista的原因的信息創建一個環境是因爲它看起來像啓動默認信息是不同的。在我設置了startupinfo結構的wShowWindow標誌之後,GUI將開始出現。

Dim StartupInfo As New STARTUPINFO() 
StartupInfo.cb = Marshal.SizeOf(StartupInfo) 
StartupInfo.dwFlags = STARTF_USESHOWWINDOW 
StartupInfo.wShowWindow = WINDOW_STATUS.SW_SHOWNORMAL 

還有一個附加信息。我試圖使用
StartupInfo.lpDesktop = "WinSta0\\Default"
設置默認桌面,因爲應用程序在啓動時會崩潰。所以我評論說。

我還有一個最後的問題。推出的應用程序並不重點。 GUI出現,但在後臺。但我在想,它將再次與上面的一些參數有關。一旦我弄清楚了,我會補充細節。

+1

嗨,我有完全相同的問題。你能發佈一個完整的示例代碼嗎?謝謝! – user670186 2012-05-27 16:09:15