2010-03-07 37 views
4

目前我正在檢查它以下列方式:如何確定是否在Windows服務中啓動?

if (Environment.UserInteractive) 
    Application.Run(new ServiceControllerForm(service)); 
else 
    ServiceBase.Run(windowsService); 

它有助於調試一點,服務也可以使用可執行文件運行。但現在假設該服務需要與用戶桌面進行交互,以便我必須在屬性中啓用「允許服務與桌面交互」。這當然打破了這種檢查方式。有另一種方法嗎?

+3

與桌面功能的交互更可靠地工作已經從Vista和Win7中刪除。這基本上解決了你的問題,如果不是現在,那麼很快。 – 2010-03-07 18:04:42

+0

可能的dup:http:// stackoverflow。com/questions/421516/how-to-write-c-service-that-i-can-run-as-a-winforms-program – 2010-03-07 18:14:35

+0

@nobugz該服務應該監視一些用戶GUI程序並保持它們運行,即使他們關閉/崩潰(一個售貨亭/終端)。看來這是真的不是一個好方法... – mikoro 2010-03-07 19:25:16

回答

5

它並不完美,但你可能會做這樣的事情:

public static bool IsService() 
{ 
    ServiceController sc = new ServiceController("MyApplication"); 
    return sc.Status == ServiceControllerStatus.StartPending; 
} 

的想法是,如果你運行這個,而你的服務仍然啓動,然後它會始終處於未決狀態。如果該服務沒有安裝,那麼該方法將始終返回false。它只會在不太可能發生的情況下失敗,即服務開始時某人正試圖同時啓動它作爲應用程序。

我不喜歡這個答案,但我認爲這可能是你能做的最好的。實際上允許相同的應用程序在服務或應用程序模式下運行不是一個好主意 - 從長遠來看,如果將所有常用功能抽象到類庫中並僅創建一個單獨的服務應用程序。但是如果由於某種原因,你真的需要有你的蛋糕並且也吃它,你可以將上面的IsService方法與Environment.UserInteractive結合起來,以獲得正確答案幾乎所有的時間。

+0

這似乎工作正常,比Environment.UserInteractive更可靠 – mikoro 2010-03-07 19:16:12

2

爲什麼不直接使用命令行開關?

// Note that you have to add the params argument, 
// which isn't usually present in windows services 
private static void Main(params string[] parameters) 
{ 
    .... 

    if (parameters.Length > 0) 
    { 
     if (parameters[0].ToLower() == "/console") 
     { 
      Application.Run(new ServiceControllerForm(service)); 
     { 
     else 
     { 
      ServiceBase.Run(windowsService); 
     } 
    } 
} 
1

除了使用Environment.UserInteractive屬性,修改服務的啓動方法來檢查「-console」命令行參數。如果參數存在,則作爲普通應用程序運行。如果沒有,則作爲服務運行。它不像屬性檢查那樣自動化,但可以很容易地在桌面上添加一個快捷方式,爲您添加「-console」命令行參數。

順便說一句,您需要知道與桌面的交互一直是disabled in Windows Vista and beyond。如果您正在運行需要與用戶交互的Windows服務,則現在批准的方式是將您的前端應用程序與Windows服務分開,並使用類似WCF的方式進行通信。

如果您需要調試Windows服務(無論是作爲服務運行還是作爲應用程序運行),請在啓動方法中調用System.Diagnostics.Debugging.Break()。這將強制提示您輸入調試會話。我一直使用這種技術來調試我的Windows服務。

4

接受的答案的問題是,檢查未安裝的服務的狀態將拋出。該IsService方法我使用看起來像這樣:

private bool IsService(string name) 
    { 
     if (!Environment.UserInteractive) return true; 
     System.ServiceProcess.ServiceController sc = new System.ServiceProcess.ServiceController(name); 
     try 
     { 
      return sc.Status == System.ServiceProcess.ServiceControllerStatus.StartPending; 
     } 
     catch(InvalidOperationException) 
     { 
      return false; 
     } 
    } 

這應該不僅僅是檢查Environment.UserInteractive

相關問題