Visual Studio 2010 Automatic Attach To Process - c#

I am using visual studio 2010, my application has a multiu layer architect,
MainUI, WCFService, BLL and DAL
My MainUI communicated to WCF and WCF further communicates to BLL and DAL, whenever i need to debug BLL and DAL, i first need to attach WCF as a process in Visual studio(everytime). How could i can save myself from this hassle.
How could i set up visual studio in a way that i automatically attach to the service automatically and i could debug my application easily.
Thanks

Configure your solution for multi project start up. I do this for a similar application. VS launches the WCF and client automatically and I can set break points in either.
The start-up order is the order in which you select the projects.
Right mouse click on your solution and select 'choose startup projects'. Then select multiple startup projects and select the projects.

Sample howto start a process and attach it to Visual Studio 2010 with EnvDTE(Version is relevant).
//c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies\EnvDTE.dll
using Process = EnvDTE.Process;
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = System.AppDomain.CurrentDomain.BaseDirectory + #"\YourProcess.exe";
//Start the process
p.Start();
//Wait for process init
System.Threading.Thread.Sleep(1000);
bool attached = false;
//did not find a better solution for this(since it's not super reliable)
for (int i = 0; i < 5; i++)
{
if (attached)
{
break;
}
try
{
EnvDTE.DTE dte2 = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.10.0");
EnvDTE.Debugger debugger = dte2.Debugger;
foreach (Process program in debugger.LocalProcesses)
{
if (program.Name.Contains("YouProcess.exe"))
{
program.Attach();
attached = true;
}
}
}
catch (Exception ex)
{
//handle execption...
}
}

Try using System.Diagnostics.Debugger.Break() in the code. If a debugger is not attached, then running that code will ask to attach a debugger and you can choose the existing instance.

Have you tried System.Diagnostics.Debugger.Launch() in your service you would like the debugger to attach to?
http://msdn.microsoft.com/en-us/library/system.diagnostics.debugger.launch.aspx

In the properties page for the wcf service project, select the Web tab.
Select 'Start External Program' for the start action, and choose MainUI.exe.
Set the working directory as the folder that MainUI.exe is in (probably a bin folder).
Set a break point and press f5 to start debugging.

If I understand correctly, Macro may be answer:
in Vs:
Tools->Macros->record TemporarilyMacro (Ctrl+shift+r)
Attach VS to process as usual (ctrl+alt+p)
Stop recording macro (ctrl+shift+r)
Go to View->Other Windows->Macro Explorer (CTRL+F8)
find your Temporarily Macro (somewhere in MyMacros->RecordingModule) and rename it
Now, go to Tools->Options->Keyboard and find your macro (in "Show Command containing write name of you macro)
in "Press Shortcut keys" bind it to some key shortcut (i have my macro in CTRL+SHIFT+K ;))
Push OK
Be Happy

Have you tried using the WCFSvcHost.EXE that comes with Visual Studio to launch the BLL and DAL service? There is a help file with it. The help file states it best, "Windows Communication Foundation (WCF) Service Host (wcfSvcHost.exe) allows you to launch the Visual Studio debugger (F5) to automatically host and test a service you have implemented. You can then test the service using WCF Test Client (wcfTestClient.exe), or your own client, to find and fix any potential errors." The default installation is C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE. You can configure it to use your MainUI app as the client. The help file WcfSvcHost.chm in the same directory has a section for using a custom client under the Scenarios for using ECF Service Host. If you rather here is the link to help on MS web site: Using WCF Service Host (wcfSvcHost.exe).

If this is for a self-hosted WCF windows service, you need to make your WCF service host configurable to either run in console or as a windows service. When you have run in console turned on, you can start debugging from visual studio.
Create an app setting called "RunInConsole." In your service host startup method, have the following code:
public class MyWindowsService : ServiceBase
{
public static void Main(string[] args)
{
// if configuration says to run in the console, run the service in a console app. otherwise, use windows
// service to host application
if (ConfigurationManager.AppSettings["RunInConsole"] == "true")
{
using (ServiceHost host = new ServiceHost(typeof(MyService)))
{
host.Open();
Console.WriteLine("Press <Enter> to terminate the Host application.");
Console.ReadLine();
}
}
else
ServiceBase.Run(new MyWindowsService ());
}
}
On all environments you deploy to, you'd always have this config setting set to false or else the service will fail to start, but when debugging locally you'd set it to true.

Here is a detained article that explains how to do this...You can customize this macro.
http://sivablogz.wordpress.com/2013/04/08/running-an-application-and-attaching-to-the-process-with-a-macro-in-visual-studio/

Personally I prefer to use Debugger.Launch() as suggested here
in this thread, because it doesn't need for references to the DTE (that's IDE-specific and must be explicitly referenced into the project to be used)

Related

Running a process from jenkins

My console application is responsible for starting a WCF service in interactive mode (ie. the service does not get installed as a Windows service in that case).
In order for my application to start the latter, the application invokes the compiled executable using the following method:
static bool AutoStartService()
{
var MyProcessFile = System.IO.Path.GetFullPath($"pathToExecutable/MyServiceExe.exe");
Process myProcess = new Process();
myProcess.StartInfo.FileName = MyProcessFile;
myProcess.StartInfo.Arguments = "";
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
myProcess.Start();
Thread.Sleep(WaitForTheServiceToStart);
}
return true;
}
Note that this approach works just fine when debugging from Visual Studio.
However, when the console application is invoked from Jenkins (note that I gave Jenkins admin access and it logs in as a normal user), then the service process does not seem to stick or be visible from the Console application. I can tell it at least starts and stops as I can see the logs being written to file.
The Console application is started using a batch command from Jenkins (I also tried using Powershell, but without luck).
Any suggestion on how to do that?
I have tried with both debug and release builds of my Console app C# project, but it makes no difference.
EDIT
I have edited the following properties, but without success:
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.Environment.Add("BUILD_ID", "dontKillMe");
I am now seeing the following warning, but I don't believe installing the service is the only way to go as this is what I am doing when running this code without Jenkins and it works. Maybe Jenkins does not allow it though?:
Cannot start service from the command line or a debugger. A Windows Service must first be installed (using installutil.exe) and then started with the ServerExplorer, Windows Services Administrative tool or the NET START command.
EDIT2
I went a step further. The reason why I was getting the former message is that the service checks "Environment.UserInteractive" to either run as interactive or to start/run the installed service. For some reasons this flag is always set to false, while it should be true in my case.
Is there a way to fool the service to think that flag is true?

Calling Web Service in a Windows Service

I've used a simple windows service to make a method work in specific time and it works fine. Following that I've already tried:
protected override void OnStart(string[] args)
{
this.WriteToFile("Simple Service started {0}");
this.ScheduleService();
}
protected override void OnStop()
{
this.WriteToFile("Simple Service stopped {0}");
this.Schedular.Dispose();
}
private Timer Schedular;
public void ScheduleService()
{
try
{
Schedular = new Timer(new TimerCallback(SchedularCallback));
string mode = ConfigurationManager.AppSettings["Mode"].ToUpper();
this.WriteToFile("Simple Service Mode: " + mode + " {0}");
//Rest of the code here
}
catch(Exception ex)
{
WriteToFile("Simple Service Error on: {0} " + ex.Message + ex.StackTrace);
//Stop the Windows Service.
using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController("SimpleService"))
{
serviceController.Stop();
}
}
}
This is done in a simple windows application. So what I am trying to do is to call a web service (A specific method to operate in a specific time) in a windows service. The application I am building is web-based and am little bit confused how would I integrate the windows service into it? Do I need any alternatives or any suggestions would be appreciated.
Note: What I would like to know is it required to create another project for windows service in the web application or any other way to implement?
To call a web service from a Windows Service application, you would first generate a DLL from that web service, then instantiate its namespace. Assuming you have the code for that web service and/or know its namespace, you can perform these commands to do this:
Perform these lines on a command line:
cd C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools
wsdl /l:CS /protocol:SOAP %svc%?WSDL
where %svc% is the URL for your web service, i.e. http://localhost:777/MyWebService.asmx
If the code is in VB instead of C#, change /l:CS to /l:VB.
This will output a proxy class file that can be converted to a DLL.
Move the MyWebService.cs file from C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools to the C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ directory.
Run these two commands on the command line:
cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
csc /t:library %name%.cs /reference:System.Web.Services.dll /optimize
where %name% is the name of the class (without the .cs, since the command will append this). In our case, we'd use MyWebService. (Change .cs to .vb for a VB class.)
Navigate to C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 via Windows Explorer. You should see a DLL created in that folder with the name of the class (MyWebService.dll). Copy this file to the bin folder of your Service project. You will need to set the bin folder to be included in your project, and right-click the folder to Add > Existing Item. Select the DLL. Once imported, select the DLL and change its properties to:
Build Action: Content
Copy to Output Directory: Copy if newer (or Copy always, as you prefer)
Right-click References > Add References. Navigate to the DLL in the bin folder for your web service.
Right-click References > Add Service References. Assuming your web service is running, take its full URL (i.e. http://localhost:777/MyWebService.asmx) and put that on the Address line. In the Namespace textbox, give it something more meaningful than ServiceReference1, but it should not be the same as MyWebService (the name/namespace of the ASMX file). Perhaps MWS.
Instantiate your web service in your Windows Service:
MWS.MyWebServiceSoapClient webService = new MWS.MyWebServiceSoapClient();
webService.Open();
string someDataYouWant = webService.SomeMethodToGetData();
webService.Close();
Or you can probably do:
MyWebService webService = new MyWebService();
string someDataYouWant = webService.SomeMethodToGetData();
webService.Dispose();
In answer to your query on my comment;
Another approach is to use an IIS Auto-Start website contaning your Windows Service logic. The IIS Auto-start is supierior to using a Windows Service as it contains all the IIS application hosting logic including auto-restart, and aggressive resource management. A poorly written Windows Service can take down a Server but it takes a lot for an ASP.net IIS hosted application to take down its host (its almost impossible).
Your Auto-Start website need not be visibile to the outside world - it just needs to have an internal timer that keeps it alive when it starts up. Note that the web application might be started and stopped by IIS for various reasons; but the outcome is that it will be running whenever your other web service application is running. The internal timer can wait for a specific time to execute the logic you need to call your second web service.
The key thing to remember is that a Windows Service is designed to be an application that is hosted by Windows and is continually running. An IIS application is designed to be run by Windows but runs only when called. The IIS Auto-Start website concept allows you to provide a "continually running" website but hosted by the robust IIS application hosting components, instead of it running directly as an OS process.
Generally people dont do this because either they dont know about it, or want to avoid needing the IIS infrastructure to run "Windows Service" type applications, but in your case you have already paid the cost of using IIS to host your second web service, so you may as well make full use of IIS (and avoid the second technology stack and deployment headaches of Windows Service deployment).
So I suggest using an IIS Auto Start in preference to a Windows Service in your situation because;
You only need to use on tech stack in your solution, which was what your OP was asking about
IIS carries out active resource management on all its applications, terminating, restarting as neccessary if they become non-functional. Windows Services do not have that capability.
Your IIS based service code is XCOPY deployable with no administrator access credentials on the target machine.
Your IIS service is hot upgradeable without needing OS level administrator rights - IIS handles the stopping and restarting on upgrade without you needing to do anything.

Cannot Start the C# application in visual Studio 12 [duplicate]

I want to debug a Windows service but it pops an error message saying
Cannot start service from the command
line or a debugger. A windows service
must be installed using
installutil.exe and then started with
the Server explorer, windows services
Administrative tools or the NET start
command.
I don't really have any idea about this error.....
Before a Windows Service can run, it has to be "installed" first using installutil. EG:
C:\installutil -i c:\path\to\project\debug\service.exe
Then you can open up the list of Services to start it. EG:
Right click 'My Computer'
Click on 'Manage'
Open up 'Services and Applications'
Click on 'Services'
Find your service in the list and right-click on it
Click on 'Start'
Once it has started, you can go into Visual Studio, click on 'Debug', then click on 'Attach to Process'.
Another technique is to add this line to your OnStart() method in the service:
System.Diagnostics.Debugger.Launch();
When you do that, it'll prompt you to pick an instance of Visual Studio to debug the service in.
You can alter the assembly's startup mode based on whether you're in DEBUG mode (usually inside Visual Studio but not necessarily) or RELEASE mode (when it runs as a service in production):
Change this:
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
}
}
to that:
static class Program
{
static void Main()
{
#if(!DEBUG)
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
#else
MyService myServ = new MyService();
myServ.Process();
// here Process is my Service function
// that will run when my service onstart is call
// you need to call your own method or function name here instead of Process();
#endif
}
}
The technique is taken from this article and the credit is for the article's author, Tejas Vaishnav. I copied the code fragments here because SO favors full answers rather than links that might disappear some time.
To prevent this error occurring and allow the service to run outside of the usual service controller you can check the Environment.UserInteractive flag. If it is set you can run the service with output to the console instead of letting it run to the ServiceBase code that returns that error.
Add this to the start of Program.Main(), before the code that uses ServiceBase to run the service:
if (Environment.UserInteractive)
{
var service = new WindowsService();
service.TestInConsole(args);
return;
}
As the OnStart and OnStop methods are protected in your service you need to add another method to that class which you can run from Main() and calls those methods for you, such as:
public void TestInConsole(string[] args)
{
Console.WriteLine($"Service starting...");
this.OnStart(args);
Console.WriteLine($"Service started. Press any key to stop.");
Console.ReadKey();
Console.WriteLine($"Service stopping...");
this.OnStop();
Console.WriteLine($"Service stopped. Closing in 5 seconds.");
System.Threading.Thread.Sleep(5000);
}
Finally, make sure the output is a console application in the project's properties.
You can now run the service executable like any other and it will start as a console. If you start it from Visual Studio the debugger will attach automatically. If you register it and start it as a service it will run properly as a service without any changes.
The only difference I've found is that when running as a console application the code does not write to the event log, you might want to output anything you would normally log there to the console as well.
This service debugging technique is one of those explained on learn.microsoft.com
There is a nuget package made to solve this problem: install-package WindowsService.Gui
What does the package do?
It helps by creating a Play/Stop/Pause UI when running with a debugger attached, but also allows the windows service to be installed and run by the Windows Services environment as well. All this with one line of code! What is Service Helper Being someone who writes Windows Services a lot, it can be frustrating to deal with the headaches involved in debugging services. Often it involves tricks, hacks, and partial workarounds to test all of your code. There is no "just hit F5" experience for Windows Services developers.
Service Helper solves this by triggering a UI to be shown if a debugger is attached that simulates (as closely as possible) the Windows Services Environment.
The github project is here: https://github.com/wolfen351/windows-service-gui
How to use?
The easiest way to get Windows Service Helper in your project is to use the NuGet package ServiceProcess.Helpers on the NuGet official feed.
Simply make a few changes to the typical code in the "Program.cs" for your application:
using System.ServiceProcess;
using ServiceProcess.Helpers; //HERE
namespace DemoService
{
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
//ServiceBase.Run(ServicesToRun);
ServicesToRun.LoadServices(); //AND HERE
}
}
}
Disclosure: I'm the maintainer of this project
Note: The UI is optional
Another reason can be that the solution configuration is in Release mode in place of Debug mode
Please check if you are in "DEBUG" or "RELEASE" mode. I got this error when I was trying to debug the service in "RELEASE" mode. When I changed that to "DEBUG", everything worked fine.
This is after you have correctly installed the service as suggested by other people above.

Testing a Web Service

I have a web service application in C#. When I run the Debug in Visual Studio, it starts the service at http://localhost:###### and shows the Default.htm page with links to test the different calls that can be made to the web service.
Is there a way to call this locally running version to test it from another computer? I tried making a call that the links on the test page make, but replaced localhost with the IP address of the machine running it, but it said that it could not connect to the server.
The embedded Visual Studio web server (Cassini) is only accessible from the local machine. If you want to use the web service from a different computer, you will need to deploy the service to IIS and then you'll be able to get to it at http://xxx.xxx.xxx.xxx/MyWebService/MyWebService.asmx (replace xxx with your IP Address and MyWebService with the appropriate IIS web site path).
Then to create a test application, you can create either an ASP.NET website or WinForms/Console application and import a Web Service reference in Visual Studio. That will build the proxy classes for you automatically and make calling the service very easy.
Just wrap your service in a console application so it can be accessed.
Create a new console application project in your solution, naming it something that makes sense (If your service is named MyService maybe MysServiceConsoleHost or some facsimile).
Include a reference to the service project in this project.
In your new project (program.cs) have something like the following:
using System;
using System.ServiceModel;
class Program
{
static String TITLE_TEXT = "MyService -- Console Host ({0})" + (System.Diagnostics.Debugger.IsAttached?" [DEBUG]":"");
static void Main(string[] args)
{
Console.Title = String.Format(TITLE_TEXT, "Not Running");
try
{
ServiceHost host = new ServiceHost(typeof(MyService));
Console.Title = String.Format(TITLE_TEXT, "Starting");
host.open();
Console.Title = String.Format(TITLE_TEXT, "Running");
Console.WriteLine("Service is started, press any key to exit.");
Console.ReadKey();
Console.Title = String.Format(TITLE_TEXT, "Closing");
host.close();
host = null;
Console.Title = String.Format(TITLE_TEXT, "Closed");
}
catch (Exception ex)
{
Console.Title = String.Format(TITLE_TEXT, "Exception");
Console.WriteLine("An error occured while running the host:");
Console.WriteLine(ex.Message);
Console.WriteLine();
Console.WriteLine(ex.StackTrace);
Console.ReadLine();
}
}
}
Replace the instances of MyService as necessary, then run it. Make sure you have a .config file that specifies the endpoints of your service, port to run on, etc. Then anyone can access your service and, if necessary, you can debug through the service during live calls.
A really simple solution to this is to use localtunnel:
http://progrium.com/localtunnel/
It will set up a proxy that will point to your localmachine and can be accessed outside of your machine.
If you are using Visual Studio's built in web server (Cassini) then this can only be called locally. If you want to connect remotely you will have to install IIS and configure your project to use it.
Yes and no. If you are using the built in ASP.NET dev server (most likely, since you have :####), I don't believe that can be contacted externally.
But, you can "deploy" to the local IIS instance and it then can be hit from other computers. Web Service Studio is a good test tool for web services. There are also some really good open source tools out there. I like SoapUI myself.
I can test the webservice on localhost. I have a windows CE Motorola terminal, connected to my computer. I have VS2008 on the computer.
My computer address is xxx.xxx.x.xxx and webserver is localhost:62209, so at the terminal i use webservice address: http://xxx.xxx.x.xxx/62209/MyWebservice.asmx and it works.
Maybe because the terminal is connected directly to the computer wher the webserver runs?
Anyway, it works.

How to debug the .NET Windows Service OnStart method?

I have code written in .NET that only fails when installed as a Windows service. The failure doesn't allow the service to even start. I can't figure out how I can step into the OnStart method.
How to: Debug Windows Service Applications gives a tantalizing clue:
Attaching to the service's process allows you to debug most but not all of the service's code; for example, because the service has already been started, you cannot debug the code in the service's OnStart method this way, or the code in the Main method that is used to load the service. One way to work around this is to create a temporary second service in your service application that exists only to aid in debugging. You can install both services, and then start this "dummy" service to load the service process. Once the temporary service has started the process, you can then use the Debug menu in Visual Studio to attach to the service process.
However, I'm not clear how it is exactly that you are supposed to create the dummy service to load the service process.
One thing you could do as a temporary workaround is to launch the debugger as the first line of code in the OnStart
System.Diagnostics.Debugger.Launch()
This will prompt you for the debugger you'd like to use. Simply have the solution already open in Visual Studio and choose that instance from the list.
I tend to add a method like this:
[Conditional("DEBUG")]
private void AttachDebugger()
{
Debugger.Break();
}
it will only get called on Debug builds of you project and it will pause execution and allow you to attach the debugger.
Once you have a service that is installed using installutil.exe, you can alter the Start Parameters to jump into the debugger if the service is started:
When you manually start the service with the parameter -debugWithVisualStudio (or simply -d), it will automatically detect the correct project, and fire up the interactive debugger in Visual Studio:
To support this functionality, change the service's OnStart() function:
/// <summary>
/// Executed when the service is started.
/// </summary>
/// <param name="args">Command line arguments.</param>
protected override void OnStart(string[] args)
{
try
{
//How to debug when running a Windows Service:
// 1. Right click on the service name in Windows Service Manager.
// 2. Select "Properties".
// 3. In "Start Parameters", enter "-d" (or "-debugWithVisualStudio").
// 4. Now, when you start the service, it will fire up Visual Studio 2012 and break on the line below.
// 5. Make sure you have UAC (User Access Control) turned off, and have Administrator privileges.
#if DEBUG
if (((ICollection<string>)args).Contains("-d")
|| ((ICollection<string>)args).Contains("-debugWithVisualStudio"))
{
Debugger.Launch(); // Launches VS2012 debugger.
}
#endif
ShellStart(args);
base.OnStart(args);
}
catch (Exception ex)
{
// Log exception here.
}
}
(optional) If you want to narrow down to the exact line of code where the service is throwing an error, switch on exceptions from the Visual Studio menu DEBUG .. Exceptions. When you continue debugging, it will break on the exact line that is throwing the exception.
It works just fine!
protected override void OnStart(string[] args)
{
System.Diagnostics.Debugger.Launch();
}
The options above did not appear to work on Windows 8.
I have added Thread.Sleep(15000); into my OnStart() method and set a breakpoint on the next line of the code. This give me 15 seconds to attach VS debugger to my process after starting the service and allowed me to debug the OnStart() method nicely.
You can add a line of code like this:
System.Diagnostics.Debugger.Break()
which will bring up a window prompting you to choose which debugger to use to debug, e.g. allowing you to attach with Visual Studio and step into the code.
see:
http://msdn.microsoft.com/en-us/library/system.diagnostics.debugger.break.aspx
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/.
Use following Code in Service OnStart Method:
System.Diagnostics.Debugger.Launch();
Choose Visual Studio option from Pop Up message. Remember to run Visual Studio as Administrator.
Note: To use it in only Debug mode, #if DEBUG compiler directive can be used, as follows. This will prevent accidental or Debugging in Release mode on Production server.
#if DEBUG
System.Diagnostics.Debugger.Launch();
#endif
As others have pointed out, you have to add a debugger break to the OnStart-Method:
#if DEBUG
System.Diagnostics.Debugger.Break()
#endif
Also start VisualStudio as Administrator and allow, that a process can automatically be debugged by a different user (as explained here):
reg add "HKCR\AppID\{E62A7A31-6025-408E-87F6-81AEB0DC9347}" /v AppIDFlags /t REG_DWORD /d 8 /f
(I also explained this here: https://stackoverflow.com/a/35715389/5132456 )
I know this is late but this is how we handle debuging Windows services
First create a class which will act as the service.
Add the appropriate methods for starting, stopping, pausing, etc...
Add a windows form to the service project.
In the service code create the service class created above and make the calls needed to start and stop the service in the ServiceBase class
Open the Program.cs and add the following
#if DEBUG
[STAThread]
#endif
static void Main()
{
try
{
#if DEBUG
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new DebugForm());
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new YourWindowsService()
};
ServiceBase.Run(ServicesToRun);
#endif
}
catch (Exception e)
{
logger.Error(DateTime.Now.ToString() + " - " + e.Source + " - " + e.ToString() + "\r\n------------------------------------\r\n");
}
}
When you run in DEBUG mode the windows form will launch. Just remember to build in Release mode when finished. Of course the conditional compile variable can be anything you like. You could even create seperate projects so the debug form is its own project.
Hope this helps
You can also try System.Diagnostics.Debugger.Launch() method. It helps in taking the debugger pointer to the specified location and you can then debug you code.
Before this step please install your service.exe using the command line of Visual Studio command prompt - installutil projectservice.exe
Then start your service from the Control Panel -> Administrative Tools -> Computer Management ->Service and Application -> Services -> Your Service Name
If you add Debugger.Launch() in your OnStart method and it doesn't work, you could have the same issue I had, namely, the exception was occurring in the constructor so the OnStart was never called. (head slap)
(sorry if this should have been a comment on someone else' answer, but i don't have enough cred to make comments)
Try adding Debugger.Break inside the problematic method. When the service will start an exception will be thrown and widows should offer to debug it using visual studio.
I usually have a console app that pretends to be the SCM e.g. calls Start, Stop which I can then just F5 into for my main coding/debugging purposes, and use the Debugger.Break for debugging when the service has been installed and started via the SCM.
It means a bit more work to start with, I have a class lib that contains all the service code, with a class that exposes Start and Stop that the Windows Service class and the console app can both call.
Matt
Before I go in the topic one advise. Always use log specially if you are server side developer. Because there are some certain condition which you might not be able to produce while debugging the code in visual studio.
Coming back to topic, I use Envoirnment.UserInteractive flag this is really handy see my code below
public static void Main(string[] args)
{
if (System.Environment.UserInteractive)
{
string parameter = string.Concat(args);
switch (parameter)
{
case "--install":
ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
break;
case "--uninstall":
ManagedInstallerClass.InstallHelper(new string[] { "/u", Assembly.GetExecutingAssembly().Location });
break;
default:
WindowsService service = new WindowsService();
service.OnStart(args);
Console.ReadKey();
service.OnStop();
break;
}
}
else
{
ServiceBase.Run(new WindowsService());
}
}
From visual studio you will get UserInteractive flag set so i would run it as console application, In addition to that even you can run product build by double clicking it and attaching debugger with it if you like to test it.
I have an interesting way of doing this I add another Configuration called DebugNoService
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugNoService|AnyCPU' ">
<OutputPath>.\</OutputPath>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
<DefineConstants>DEBUG;TRACE;DEBUGNOSERVICE</DefineConstants>
<DocumentationFile>
</DocumentationFile>
<DebugSymbols>true</DebugSymbols>
<FileAlignment>4096</FileAlignment>
<NoStdLib>false</NoStdLib>
<NoWarn>
</NoWarn>
<Optimize>false</Optimize>
<RegisterForComInterop>false</RegisterForComInterop>
<RemoveIntegerChecks>false</RemoveIntegerChecks>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<WarningLevel>4</WarningLevel>
<DebugType>full</DebugType>
<ErrorReport>prompt</ErrorReport>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
I use the #if directive.
ProjectInstaller.cs
#if !DEBUGNOSERVICE
static void Main()
{
System.ServiceProcess.ServiceBase[] ServicesToRun;
.....
}
#endif
I add a windows form and I also wrap the windows form in
#if DEBUGNOSERVICE
...
static void Main()
{
Form form;
Application.EnableVisualStyles();
Application.DoEvents();
form = new <the name of the form>();
Application.Run(form);
}
...
#endif
depending on the configuration selected the code either runs as a windows form application that can be easily debugged or as a service.
If seems like a lot of work but it has always worked and makes debugging the code very very easy. You can have all sorts of output added to the form so you can watch it run.

Categories

Resources