Windows Service without Visual Studio interference
I'd like to create and manage a Windows Service application without "help" from Visual Studio's designer.
Since this is .NET, and judging by MSDN and what the designer does, this means inheriting from Installer
, and constructing and dealing with ServiceProcessInstaller
and ServiceInstaller
to be able to manage the install-time execution of the serivce.
Runtime, this means creating a ServiceBase
subclass and starting it from Main
using ServiceBase.Run
(and overriding various ServiceBase
event handling methods).
However, when I do this, Visual studio insists on treating the Installer
and ServiceBase
subclasses as designer-edited files. This doesn't exactly help readability开发者_如何学JAVA, not to mention the fact that it generally can't deal with handwritten code at all. I'd like to avoid the designer to keep things manageable (to avoid nebulous who-knows-what-runs-when, particularly for code that's tricky to test and debug such as windows services that after all must be installed to be run at all), and also to be able to specify the service name at run-time, rather than at compile time - the designer doesn't support that.
How can I create a windows service application without all the gunk?
ServiceBase
is derived from Component
. To disable the designer view you can attach the attribute like so:
[System.ComponentModel.DesignerCategory("Code")]
public class MyService : ServiceBase
{
}
Since I often create services do it like this:
I have a common base class that looks like this:
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);
}
Then I create all my services like this
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();
}
}
Now I can test the service by just running it in the debugger or on the command line.
When installing I use the command line
sc create ServiceName binPath= C:\...\MyService.exe
(I have not been able to stop the designer from opening on double click)
Well, just delete the InitializeComponent() call in the constructor and the designer generated code is out of your hair.
VS does add some extra stuff but I wouldn't really worry about it. Here's a tutorial for creating a simple service manually in VS2005, it should work just fine for new versions, too.
http://www.codeproject.com/KB/system/WindowsService.aspx
精彩评论