 |
|
 |
I recently wanted to do something similar. I wanted to be able to run my program as both a windows service and a standalone console application, and be able to debug it without the hassle of installing it as a service. I came up with a way to make it work, that doesn't include special builds, #DEBUG directives, command line parameters or anything like that. I just wrote down my solution at: http://tech.einaregilsson.com/2007/08/15/run-windows-service-as-a-console-program/
Hope it can be useful for someone
|
|
|
|
 |
|
 |
A simple approach to debug .NET service!
Thanks
nn coder
|
|
|
|
 |
|
 |
Thank you so much, so easy!
Best regards,
Christian
|
|
|
|
 |
|
 |
I came up with what I think is a cleaner way to do this, perhaps you will agree:
Instead of using the #if compiler conditional to test for debug mode, which is perfect except for (as you mentioned) having to switch between Debug/Release mode all the time, you can use a command-line argument. Set the command line argument to "debugmode" or something simliar on the Debug tab in your project properties, then test for the existence of this argument in Main. Now when you run the project from Visual Studio, the command line arg will be set and you'll always run the non-service code; outside of Visual Studio, your app will run only as a Windows service.
// The main entry point for the process
static void Main(string[] args) {
if(args.Length > 0 && args[0] == "debugmode") {
// Debug code: this allows the process to run as a non-service.
// It will kick off the service start point, but never kill it.
// Shut down the debugger to exit
Service1 service = new Service1();
service.();
// Put a breakpoint on the following line to always catch
// your service when it has finished its work
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
} else {
System.ServiceProcess.ServiceBase[] ServicesToRun;
ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Service1() };
System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}
}
|
|
|
|
 |
|
 |
Yep that would work - the only issue with it is the extra step to add the commandline argument (trivial) and of course the chance that you may release debug code as a service. With my one it really didn't behave well if you tried to run the debug version as a service - so you knew when you had screwed up and put out a debug build.
|
|
|
|
 |
|
 |
I cannot get this work at all.
What is Service1 ?
-- modified at 18:04 Tuesday 29th May, 2007
|
|
|
|
 |
|
 |
If you're simply cutting and pasting from the article - then you won't get anywhere. You need to follow the instructions in the article and create a new C# Windows Service project in Visual Studio, once you've done that you'll be left with a service class called Service1. You would normally change this name to something more suitable and put in your current Service code.
The Service1 code itself would probably look like:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Text;
namespace WindowsService1
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
// TODO: Add code here to start your service.
}
protected override void OnStop()
{
// TODO: Add code here to perform any tear-down necessary to stop your service.
}
}
}
|
|
|
|
 |
|
 |
Well I have service that is running I am trying make changes to it and need to do debug. The item in the service is OnStart. Which does not work. Error message = No overload for method 'OnStart' takes '0' arguments
|
|
|
|
 |
|
 |
In which case I'd still recommend building a new service, making the changes I described and then transferring over that 'model' to your existing service. After that read through the comments below which discuss some options related to OnStart.
|
|
|
|
 |
|
 |
Nice Work, Thanks!
"Simplicity is the ultimate sophistication" - Leonardo Da Vinci
|
|
|
|
 |
|
 |
Hello...
I have a Windows Service that in OnStart method set 2 timers that tick when determined time has elapsed.
I can debug OnStart method using your technique, but the timers never get called. Any way to do it?
Thanks
|
|
|
|
 |
|
 |
Hi Nicholas,
The two simplest options are:
Stick the initiation of the two timers into a separate method called by both the OnStart and the Debug code.
Directly call the OnStart method from the Debug code.
Neither is rocket science but then neither is this technique. I would doubt that there would be any other issues, for instance with the event handlers for your timers, it should just go.
Regards, Lee
|
|
|
|
 |
|
 |
I've had this issue when I used the wrong Timer before. Never have figured this out, but it seems to me if you are using a System.Windows.Forms.Timer vs. a System.Timers.Timer you get different functionality, especially in a service.
Try out the opposite timer (probably you'll want to stick with System.Timers.Timer).
|
|
|
|
 |
|
 |
Thankx a lot Lee.
You saved me hell lots of time.
Simple but simply great !
jimmy
Jimmy S
|
|
|
|
 |
|
 |
Often the simplest things are the most amazing...I'm obviously easily impressed.
Suggestions offered by jriesen below were also very useful.
Thanks very much
|
|
|
|
 |
|
 |
Nice job!
Thanks
fsdafsda
|
|
|
|
 |
|
|
 |
|
 |
Your solution looks like you actually thought about it.
I originally also borrowed the first idea of using a #DEBUG directive for debugging a service. Unfortunately the rest of that code was a bit too much 'crude' rather than 'effective'. But it has been interesting to watch the pieces come together on this issue. Actually that's kind of worrying considering how long ago I first wrote this article. Maybe Macroslop will *borrow* your idea as part of the default template for windows service projects.
|
|
|
|
 |
|
 |
Hah! That'd be something.
The solution I came up with has a flaw though: it only tests the methods you implement on the service, not its ability to live in the Windows Services environment. At least accurately, anyway.
For example, if you (for some reason) didn't know you couldn't put UI code in a service without first checking "Allow Service to Interact with the Desktop" (a terrible practice anyway), then you wouldn't find this bug until you installed the service with installutil.exe and ran it from there. Similarly, you are going to have problems with calls to this.EventLog.Write* because the service won't be installed and therefore the event log won't have information for your service registered with it yet.
These kinds of issues come up no matter what solution you try. It's sad that they can't have special support in VS for debugging these things. Maybe in Orcas?
|
|
|
|
 |
|
 |
I like to use System.Environment.MachineName to base my debugging on. if I'm in development environment then I do one thing else I use production resources.
|
|
|
|
 |
|
 |
In more recent versions of this project I've gone and done the same.
|
|
|
|
 |
|
 |
myFeedback = "Thank you, thank you, thank you ...";
|
|
|
|
 |
|
 |
Thanks, Lee - I love elegant and simple solutions. I am going to incorporate this into a template so the code is automatically inserted when I spin up a new service project!
-Dave Ferreira
It IS what you say, not just how you say it!
|
|
|
|
 |
|
 |
I don't know about elegant - but simple, yep I'd agree with that.
I'd also suggest reading some of the more recent comments below. Some others have made some great contributions that add the missing elegance to my code above.
Next, a XAML management console where if you highlight the rotating spotlight beam while licking the USB port on your DNS server (may require virtual tongue - that's another project) you get a mocked up terminal services window showing the state of your service in glorious surround sound.
|
|
|
|
 |
|
 |
That would only rate a 3. You should use a Firewire 800 virtual tongue instead of a USB, and while surround sound is nice in a late 80's kind of way, you should try creating a VR world using Aero. Of course, that's just my opinion - I could be wrong.
Everyone's a critic.....
-Dave Ferreira
"When everyone is out to get you, paranoia is just good thinking...."
|
|
|
|
 |