2011-04-02 122 views
1

我設計了定期檢查特定的應用程序是否安裝,當它發現它沒有安裝,下載它從共享網絡位置的Windows服務安裝包的問題,​​該文件是一個無聲無息地安裝exe(自行安裝)。C#Windows服務運行

我有運行安裝程序問題,所以我決定,而不是試圖運行安裝程序,運行一個小的hello world Windows窗體應用程序,只是爲了看看這個簡單的事情的作品。

幾個困惑小時後我終於發現的hello world應用程序不會在實際上運行,但不同的用戶下 - 特別是本地機器。在接下來的幾個小時裏,我發現我必須關閉UAC(Vista/7)並允許該服務與桌面交互。在此之後,我終於在桌面上得到了一個提示,表明服務正在嘗試運行某些內容,而且我必須決定是否允許它。

當我按下允許 - 我帶到另一個GUI(從我的桌面不同)和世界你好此後正常運行。

現在,儘管這當然是一個進步,但我仍然遠離在當前用戶帳戶下安裝應用程序。

我遇到的一個問題是將windows服務設置爲以特定用戶身份運行,當我在該類型的WS上使用installutil.exe時,它提示我輸入用戶名和密碼,輸入正確的(管理員特權)數據並且無法安裝。

我想要實現的是讓Windows服務以任何方式安裝無提示安裝程序包而不中斷用戶,測試無提示安裝程序包是net framework 2.0 - 我需要安裝它,就好像用戶單擊它一樣本人。

我不要求任何代碼(但是這會受到歡迎),只是點我朝着正確的方向,在此先感謝!

+0

我不確定問題是什麼,但Windows服務,屏幕保護程序和其他系統進程運行在不同的UI環境或不同的桌面。據我所知,可以使GUI在登錄用戶的上下文中運行(如果有的話)。 – kenny 2011-04-02 11:11:48

回答

1

我不知道它是如何在C#中完成的,但我會解釋這個概念。

當您在Windows服務是你的應用程序運行系統用戶,由於已經進行的任何登錄甚至在應用程序運行。

此外,從win7本地服務帳戶不能顯示GUI,因爲主要的安全問題,如導致應用程序運行cmd.exe任何類型的資源管理器,允許用戶執行他/她不應該做的事情(我認爲你可以繞過這一點,不確定,但不建議反正,所以不要)。

所以,你有2種選擇:

  1. 創建將用戶的會話中運行其他應用程序,你可以使用RPC(如.Net遠程)與它通信。您可以將應用程序放置在用戶的啓動中。我認爲更好的方法是使用CreateProcessAsUser()(我不知道它是如何在C#中調用的)。每個用戶都有一個令牌,因爲你是一個服務,你有權獲得用戶的主令牌,這將允許你在用戶帳戶下創建進程。 CreateProcessAsUser()創建一個進程,它也獲得一個令牌來以該用戶身份運行進程。

關於令牌的一些更多的事情,對於CreateProcessAsUser你需要獲得用戶的令牌。使用WTSQuestUserToken從Windows服務(僅限Windows服務)執行此操作的最簡單方法是使用WTSQuestUserToken。您爲該函數提供用戶會話的sessionID,並返回主令牌。

這種方法並不完美,但它很容易適用於大多數情況。如果在同一個會話ID(sessionID ==終端服務器會話ID)下有兩個用戶,則可以使用從資源管理器運行時完成。但我想我得到的答案足夠複雜,所以如果你的WTSQueryUserToken()對你來說不夠好,讓我知道,我會更徹底地解釋(顯然它會更復雜)。

祝你好運!

+0

管理層認爲這將是最好的解決方案 - 我從一開始就反對。與此同時,我確實設法向管理層強調,由於時間是第一問題,我們必須重構整個邏輯。 – BrunoBozic 2011-04-04 07:45:59

+0

因此,我將一個小應用程序作爲無人照管的靜默Inno安裝程序包進行部署,此幫助程序應用程序向計劃任務添加一個計劃事件(在用戶登錄時) - 啓動我需要的應用程序。 – BrunoBozic 2011-04-04 07:47:13

+0

另一個額外的好處是 - 能夠通過多臺機器上的VBScript推送這樣的軟件包(Inno Setup)。所以基本上我們通過使用不同的方法來達到同樣的目的。當然,管理層希望我繼續用windows服務來調查這個問題,因爲這些問題仍然是他們感興趣的問題,因爲某些原因,他們認爲它們是100%可靠的東西(相對於任務調度程序的例子) – BrunoBozic 2011-04-04 07:49:12

1

爲什麼你所看到的行爲,你的描述我的答案herehere你會發現足夠詳細的解釋,如果你很好奇。

但無論如何,解決方案是找到一種替代方法。 Windows服務無法顯示用戶界面,並且無法在特定用戶的上下文中運行。他們根本不是你想要做的事情的可行選擇。禁用UAC也是而不是是一個可接受的選項。

很難想象爲什麼您需要首先從Windows服務中執行此操作。用戶登錄時運行的後臺進程似乎是更好的方法。它根本不需要任何界面,但它仍然可以彈出一個窗口,或者在用戶選擇時與用戶進行交互。

+0

我同意。特別是禁用UAC部分。 – BrunoBozic 2011-04-04 07:54:01

+0

有人認爲,Windows服務是最好的地方放置一個應用程序,檢查一個exe文件的網絡驅動器,如果該exe文件符合某些reqs,下載並安裝它。我們這裏沒有AD,因此管理層希望我們設計一種通過網絡部署應用的方式。他們設計了Windows服務定期檢查文件網絡位置的規範,如果需要的話將其下載並安裝(另一個考慮是運行帶有進度條的GUI)。 – BrunoBozic 2011-04-04 07:56:54

+0

@布魯諾:不幸的是,那個認爲是錯誤的人*。這不會起作用。當你讓那些對編程一無所知的人開發你的規範時,會發生這種情況。與真實世界完全脫節的規格對任何人都沒有任何好處,即使是寫這些的人也是如此。在Windows服務上有一個GUI(有或沒有進度條)是簡單的**不可能**。這不是他們設計的。閱讀你的其他評論,我更加確信後臺流程就是答案。改爲實施;如果有必要,寫下你自己的規範 – 2011-04-04 09:23:08