簡體   English   中英

C#從Service(和Vista)運行Windows Form Application

[英]C# Run Windows Form Application from Service (and in Vista)

我正在用C#編寫一個需要作為服務運行但也需要用戶交互的應用程序。 我知道服務沒有UI等,因此我將程序分為Windows窗體應用程序和可以相互通信的服務。

我遇到的問題是,我需要該服務以確保Windows窗體應用程序始終處於運行狀態,如果沒有運行,請重新啟動它。 我能夠檢測它是否正在運行,並在Windows 2000 / XP上使用以下代碼重新啟動它:

System.Diagnostics.Process.Start("ExePath");

但是在Vista上,它會將新進程作為本地/系統進程運行,對用戶不可見。 有人繞過這個嗎? 有什么方法可以檢測到哪個用戶當前已登錄並以該用戶身份運行新進程? 在這一點上,我不需要考慮快速用戶切換。 基本的東西(任何東西)就足夠了。

如果您對此有任何幫助或提示,我將不勝感激。

我需要說明的是,在安裝服務時,我正在設置“允許服務與桌面交互”選項。 這就是它可以在2000 / XP上運行的原因。 但是,Vista仍然存在上述問題。

這種事情的總體思路是,如果用戶需要與服務進行交互,則他們應該啟動一個單獨的應用程序。 如果要幫助他們,可以通過在啟動菜單中放置快捷方式,將該單獨的應用程序配置為從Windows啟動。 您還可以在應用程序中內置崩潰恢復,以便它可以自動重新啟動。

您不應該真正依賴監視表單應用程序,如果沒有人登錄怎么辦? 如果多個人登錄怎么辦? 這樣只會使事情變得混亂。

將服務放在那兒並向聽眾廣播是一種方法。 表單應用程序啟動時,它可以通知服務它要監聽事件。

看到問題: Windows服務如何執行GUI應用程序? 它解決了C / C ++中的相同問題(簡短答案:CreateProcessAsUser),但是答案對於C#仍然有效(帶有一些P / Invoke)。

在這種情況下,您將必須具有第三個監視進程,該進程將檢測程序是否失敗並在這種情況下重新啟動它。

但是,這里最終會遇到無法解決的問題,因為必須監視監視器進程以確保它不會關閉,依此類推,依此類推。

您可能需要重新考慮這種方法。

要讓您的服務以用戶身份運行應用程序(這似乎是您要嘗試的操作),您需要執行以下操作:

System.Security.SecureString ss = new System.Security.SecureString();

foreach (char c in password)
  ss.AppendChar(c);

System.Diagnostics.Process proc = Process.Start(path, arguments, username, ss, domain);

哪里:

  • path =可執行文件的完整路徑(包括文件名)。
  • arguments =參數字符串(使用空字符串為none)
  • username =服務器/計算機上的用戶帳戶名稱
  • 域=您的網絡域(如果您使用的是網絡帳戶,則為空;如果沒有)

另外,為了使您的服務具有啟動應用程序的權限,它還必須作為服務運行。 為此,您需要將這些行添加到服務安裝程序類中:

serviceProcessInstaller.Account = ServiceAccount.User;

serviceProcessInstaller.Username = "yourdomain\\yourAccountName"; //Or just "AccountName" for local accounts..            

serviceProcessInstaller.Password = "yourPassword";

這是一個艱難的局面。 正如在幾個地方提到的那樣,如果您必須具有UI,那么從技術上講,您不應該使用服務。 畢竟,服務在沒有用戶登錄的情況下運行。 如果沒有人登錄,則無法使用UI。

通常,當我需要與外界溝通的服務時,我會選擇兩件事。 我可以在事件日志中放置一個條目,也可以將消息放入隊列中。

在您的情況下,我將使用隊列。 用戶登錄后,您可以自動為他們啟動監視隊列的應用程序。 如果應用程序正在運行,則在收到消息后,也會以這種方式提醒他們。 但是,如果用戶關閉應用程序,則會發生相同的事情……他們不會知道。

首先,一個簡單的答案:“允許服務與桌面交互”選項(服務->屬性->登錄)或指定帳戶是否允許您所需? 如果是這樣,則可以在您的服務安裝程序類上配置這兩者。

像其他應用程序一樣,我懷疑有更好的方法,以下任一情況都適用:-服務中的代碼可以包含在winforms應用程序中(也許在后台線程中運行),並添加到Windows啟動中。 兩者都將運行-Winforms應用程序可以在打開時僅偵聽該服務,而無需從該服務啟動。 或者類似地,可以將應用添加到啟動中。

在Windows 2000和XP中,服務屬性窗口的“登錄”選項卡上有一個選項(復選框),以允許服務與桌面進行交互。 我相信這就是您要尋找的。 我剛剛在VB.NET中使用Process.Start(“ calc.exe”)編寫了一項快速服務,並且Windows Calculator打開得很好。

我不是100%地確定這在Vista中是否能以相同的方式工作。

聽起來您可能不需要一半的服務作為服務運行(除非需要更高的特權),因為當沒有交互式用戶登錄時,您的服務也需要處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM