Visual Studio debugging windows services
Tags: csharp, dotnetcore, productivity
Published: 2023-12-02 11:13:53

## Introduction
Building Windows services can be challenging, especially for developers whom never written a Window service before. Most documentation including Microsoft warns that a developer should not attach to a process unless you know what the process is and understand the consequences of attaching to and possibly killing that process. This is true when running any project that code not reviewed. This changes slightly when the developer wrote code and wants to debug the service. This article provides details on debugging a Windows service after there has been a code review.


![Shows dialog for debugging a service](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3zplk9urfiv60f8ivtm5.png)

## Installing the service

Use [Installutil.exe](https://learn.microsoft.com/en-us/dotnet/framework/tools/installutil-exe-installer-tool) The Installer tool is a command-line utility that allows you to install and uninstall server resources by executing the installer components in specified assemblies.

Alternate method to install is with the [following tool](https://github.com/karenpayneoregon/WindowsInstaller) which was written in .NET Framework, not .NET Core but if needed would be easy to convert to .NET Core Framework yet see zero reasons for this.


![Windows service utility](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/osjo153ls8yf7g0w4i7b.png)

## Project setup

Open the service solution in Visual Studio; open the window service to debug, make sure the project is setup for debug under project properties, Build tab. “Define DEBUG constant” must be checked and the Configuration ComboBox must be set to “Active (Debug)” or “Debug”.

## Debug point

Place the following into the OnStart event of the service.

```csharp
#if DEBUG
  Debugger.Launch();
#endif
```

With the service project as the startup project, click “start” in the IDE toolbar. When the breakpoint is hit on Windows 7 a prompt appears, answer yes to debug then select the open instance of Visual Studio to use to debug. Once this has been done Visual Studio will break on [Debugger.Launch](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.debugger.launch?view=netcore-3.1). Step through the code and notice there is no difference in debugging any other project type.

Windows 8 and higher have tighten security so that when Debugger.Launch is hit there will be additional prompts to jump through which can become a nuance when there is a need for many debug sessions as this is the best method to figure out why code which looks good is not working as expected.

The solution for Windows 8 and higher is to first open RegEdit to 

```
HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\EnableLUA registry
```

**Change the value from 1 to 0**. This will invoke a prompt from Windows indicating for the change to take affect this computer requires a reboot. Once the system has restarted, open Visual Studio to the Windows Service solution and start the service. At this point the additional security prompts will not appear.

The solution mentioned for Windows 8 and higher is not documented by Microsoft; this information was obtained by the Microsoft team responsible for the Visual Studio debugger and may change in updates to Windows operating system, not Visual Studio. 

## Warning

Disabling UAC  (as done by altering the registry value above) is not advisable as this raises chances of security breach to a computer. This should only be done when the service source is not from an unknown source. Only use the registry setting mentioned above for the time it takes to write code for a service followed by enabling UAC when finished.

## Summary

Using techniques presented allow developers to debug window services on Windows 7 and higher machines. Using techniques for Windows 8 and above allow less security prompts by lowering UAC (User Account Control) which means the computer is less safe thus important to enable the setting in the registry back to it’s default.