2011-02-09 68 views
7

我想創建和管理Windows服務應用程序,而不需要Visual Studio設計人員的「幫助」。沒有Visual Studio干擾的Windows服務

由於這是.NET和MSDN通過判斷和設計師做什麼,這意味着從Installer繼承,並構建和處理ServiceProcessInstallerServiceInstaller要能管理中的service的安裝時執行。

運行時,這意味着在創建子類ServiceBase並使用ServiceBase.Run(和壓倒一切的各種ServiceBase事件處理方法)從Main啓動它。

但是,當我這樣做時,Visual Studio堅持將InstallerServiceBase子類視爲設計者編輯的文件。這並不完全有助於可讀性,更不用說它通常無法處理手寫代碼的事實。 我想避免設計師保持可管理性(以避免模糊的誰知道什麼運行時,特別是對於難以測試和調試的代碼,例如windows服務,所有必須必須安裝到完全可以運行),並且還能夠在運行時指定服務名稱,而不是在編譯時 - 設計人員不支持這一點。

如何創建一個沒有所有垃圾的Windows服務應用程序?

+2

你可能想看看TopShelf項目 - http://topshelf-project.com/ – stuartd 2011-02-09 15:48:58

+0

嗯 - 整齊!看起來有點矯枉過正,還不夠成熟,但如果我要寫一個新的應用程序,我一定會考慮它。 – 2011-02-10 13:59:32

回答

-1

VS增加了一些額外的東西,但我不會真的擔心它。這裏有一個教程,用於在VS2005中手動創建一個簡單的服務,它對新版本也應該很好。

http://www.codeproject.com/KB/system/WindowsService.aspx

+1

當「ServiceName」不是常量時,設計器崩潰 - 它改變了我寫的代碼:我真的不想讓設計師。而且,它生成的代碼比所需的代碼容易5倍,並且不太容易理解。 – 2011-02-09 14:50:23

+1

讓我這樣說吧:除了作爲包含所需類型的初始模板之外,還有其他*有用的功能嗎? – 2011-02-09 14:54:06

2

嘛,只是刪除在構造函數在InitializeComponent()調用和設計器生成的代碼是你的頭髮的。

5

因爲我通常會創建服務做這樣的:

我有一個共同的基類,看起來像這樣:

internal class ServiceRunner : ServiceBase { 
    protected static void Startup(string[] args, ServiceRunner instance, bool interactiveWait) {  
    if (instance == null) 
     throw new ArgumentNullException("instance"); 

    if (Environment.UserInteractive) { 
     instance.OnStart(args); 
     if (interactiveWait) { 
      Console.WriteLine("Press any key to stop service"); 
      Console.ReadKey(); 
     } 
     instance.OnStop(); 
    } 
    else 
     Run(instance); 
} 

然後,我創建我的所有服務這樣

internal class MyService : ServiceRunner 
{ 
    public MyService() { 
     ServiceName = ConfigurationManager.AppSettings["MyServiceName"]; 
    } 

    private static void Main(string[] args) { 
     Startup(args, new MyService(), true); 
    } 

    protected override void OnStart(string[] args) { 
     base.OnStart(args); 
     ... 
    } 

    protected override void OnStop() { 
     ... 
     base.OnStop(); 
    } 
} 

現在我可以通過在調試器或命令行中運行它來測試服務。

安裝時我使用命令行

sc create ServiceName binPath= C:\...\MyService.exe 

(我一直無法從上雙擊打開停止設計師)

8

ServiceBaseComponent的。要禁用設計視圖中可以附加屬性,像這樣:

[System.ComponentModel.DesignerCategory("Code")] 
public class MyService : ServiceBase 
{ 

}