how to run(F5) windows service from visual studio
How 开发者_JS百科to run a windows service project from visual studio.
I am building a windows serivce in visual studio 2008, I have to always run the service from control panel and then attach the debugger to running instance of the service. Its kind of annoying since I am cleaning a lot of code and need to restart my service many times during development.
I want to setup my project so as to be able to hit F5 and run the service and directly enter the debug mode. Some tips on how to achieve this would be great.
Thanks in advance!!!
Copied from here.
static void Main(string[] args)
{
DemoService service = new DemoService();
if (Environment.UserInteractive)
{
service.OnStart(args);
Console.WriteLine("Press any key to stop program");
Console.Read();
service.OnStop();
}
else
{
ServiceBase.Run(service);
}
}
This should allow you to run from within Visual Studio.
Another way would be to embed a programmatic breakpoint in your code by calling System.Diagnostics.Debugger.Break()
. When you place this in, say, the OnStart() callback of your service and start your service from the Services console, the programmatic breakpoint will trigger a dialog box that allows you to attach to an existing instance of Visual Studio or to start a new instance. This is actually the mechanism I use to debug my service.
In your Main()
routine check for Debugger.IsAttached
and if it's true start your app as if it's a console, if not, call into ServiceBase.Run()
.
It's possible to set up a companion project to the Windows Service that runs as a console app, but accesses the service methods using Reflection. See here for details and an example: http://ryan.kohn.ca/articles/how-to-debug-a-windows-service-in-csharp-using-reflection/.
Here is the relevant code that you'll need in the console application:
using System;
using System.Reflection;
namespace TestableWindowsService
{
class TestProgram
{
static void Main()
{
Service1 service = new Service1();
Type service1Type = typeof (Service1);
MethodInfo onStart = service1Type.GetMethod("OnStart", BindingFlags.NonPublic | BindingFlags.Instance); //retrieve the OnStart method so it can be called from here
onStart.Invoke(service, new object[] {null}); //call the OnStart method
}
}
}
You can also do this: (See comments for explanation)
public class Program : ServiceBase
{
private ServiceHost _serviceHost = null;
public Program()
{
ServiceName = "";
}
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
#if(!DEBUG)
// when deployed(built on release Configuration) to machine as windows service use this
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[] { new Program() };
ServiceBase.Run(ServicesToRun);
#else
// when debugging use this (When debugging after building in Debug Configuration)
//If you want the DEBUG preprocessor constant in Release you will have to check it on in the project configuration
Program progsvc = new Program();
progsvc.OnStart(new string[] { });
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#endif
}
protected override void OnStart(string[] args)
{
// Start Web Service
if (_serviceHost != null)
{
_serviceHost.Close();
}
_serviceHost = new ServiceHost(typeof(Namespace.Service));
_serviceHost.Open();
}
}
Create a seperate project that just references the service project and instantiate and start the service. It just runs like a normal app and you can step into it.
YourService s = new YourService();
s.Start();
Just call the OnStart() event from the service constructor
I did it in the following way
public XXX()
{
InitializeComponent();
OnStart(new string[] { "shafi", "moshy" });
}
You want to have your windows service as a shell, there should be little code in there so you don't have to test it.
You should have every thing you want your service to do in a class.
You can unit test you class and if it works then reference it to your service.
This way when you have you class doing every thing you want then when its applied to your service every thing should work. :)
Will an event log you can see what your service is doing while it is running, also a nice way to test :D try that.
namespace WindowsService
{
public partial class MyService : ServiceBase
{
public MyEmailService()
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("MySource")) // Log every event
{
System.Diagnostics.EventLog.CreateEventSource(
"MySource", "MyNewLog"); // Create event source can view in Server explorer
}
eventLogEmail.Source = "MySource";
eventLogEmail.Log = "MyNewLog";
clsRetriveEmail Emails = new clsRetriveEmail();
eventLogEmail.WriteEntry("Populateing database with mail"); // log event
Emails.EmailGetList(); // Call class
}
protected override void OnStart(string[] args)
{
eventLogEmail.WriteEntry("Started");
}
protected override void OnStop()
{
eventLogEmail.WriteEntry("Stopped");
}
protected override void OnContinue()
{
eventLogEmail.WriteEntry("Continuing");
}
}
}
These links can be very helpful when working with services.
This is a walk though on creating them http://msdn.microsoft.com/en-us/library/zt39148a.aspx
James Michael Hare has on his blog http://geekswithblogs.net/BlackRabbitCoder/ written about a really nice template/framework he has made, making it lot easier to develop (and debug) Windows Services: C# Toolbox: A Debuggable, Self-Installing Windows Service Template (1 of 2) http://geekswithblogs.net/BlackRabbitCoder/archive/2010/09/23/c-windows-services-1-of-2-creating-a-debuggable-windows.aspx
It provides you with all the basics you need to quickly get started. And best of all, it give you a really nice way to debug your service as if it was a regular console application. I could also mention that it provides out of the box functionality to install (and uninstall) your service. Part two of the post can be found at this link.
I've used this myself a couple of times, and can really recommend it.
精彩评论