2011-02-09 73 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 
{ 

}