Run a Windows Service as a console app
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.
6 Answers 6
Before a Windows Service can run, it has to be «installed» first using installutil. EG:
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:
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):
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.
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.
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:
Disclosure: I’m the maintainer of this project
Note: The UI is optional
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:
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:
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.
Run a process from a windows service as the current user
I currently have a windows service that is running under the System Account. My problem is that i need to start certain processes from within the service as the current logged on user. I have all the code etc to get the current logged on user / Active session.
My problem is that i need spawn a process as the logged on user but will not know the user credentials etc.
The service is .net compiled service and i expect that i need to use some Pinvoke methods to get a handle of one of the current users process in order to duplicate it and lunch as process with the handle.
Unfortunately i cannot find any good documentation / solution on how to implement it?
If someone is able to give me some guidance / example i would highly appreciate it.
* Updated * I think i have explained this incorrectly and need to reajust according to what i actually require. I do not necessarily want to launch a new process, i just want to impersonate the logged on user. I have been so wrapped up at looking at CreateProcess etc i have lead myself down a path of create a new process as the current logged in user (which is not particularly what i want to do).
In turn i just want to run some code under the current user context (Impersonate the current Logged on user)?
2 Answers 2
One option is to have background application that automatically starts when user logs on and listens to commands from your service through WCF, or thrift, or by just monitoring some file and reading command from there.
Another option is to do what you originally asked for — launch using windows API. But the code is quite scary. Here is a sample, that you can use. It will execute any command line under currently active user session, with CreateProcessInConsoleSession method:
As is so common with these types of questions about Windows services, you’re operating in the mindset of a single-user operating system. The whole reason you decided to write your app as a service was because you were running into conflicts between your mental model of a single-user OS and the reality of a multi-user OS. Unfortunately, a service didn’t solve all of your problems and now you’re trying to figure out how to accomplish step two in the ultimately-doomed hacked design.
The fact is, you cannot be guaranteed that there is a «logged on user». If no one has logged on to the workstation, there will be no one logged on, yet your service will still be running.
Even if you somehow got past this by ensuring that someone will always be logged on (impossible), then you would run into the situation where multiple users are logged on. Then which one should your service start the process as? Should it just pick one of them randomly?
And is it necessary in your case to distinguish between users logged on locally to the console and those who are logged on remotely? Remember that remote users won’t have a local console.
If you could somehow get past all of these hurdles (unfortunately, probably by burying your head in the sand and continuing to pretend that Windows is a single-user OS), you could make use of the WTSGetActiveConsoleSessionId function to obtain the current session ID, the WTSQueryUserToken function to obtain the user token corresponding to that session ID, and then finally the CreateProcessAsUser function to launch your process in the context of that user. If there is one. And they have the appropriate privileges. And the physical console is not attached to a dummy session. And you’re not running a server SKU that allows multiple active console sessions. And…
If you could decide on a particular user whose account you wish to use to start the auxiliary process, you could log on that user, manipulate their user token, execute the process, and finally close the process and log out the user. The CreateProcessWithLogonUser function wraps up a lot of this drudgery for you, making the code a lot more svelte. But appearances can be deceiving, and this still has some massive security implications that you probably do not completely understand if you’re asking this question in the first place. And you really cannot afford to not understand security risks like this.
Besides, users that are logged in with LogonUser (which is done for you automatically when you use the CreateProcessWithLogonUser function) lack a window station and desktop on which they can launch interactive processes. So if the process you wish to launch in the context of that user will show any kind of UI, you’re out of luck. Windows will kill your app as soon as it tries to access a desktop for which it lacks the requisite permissions. There is no way, from a Windows service, to obtain the handle of a desktop that will be useful to you (which goes a long way towards explaining the general rule you probably already know, that services cannot display any type of UI).
Create Windows service from executable
Is there any quick way to, given an executable file, create a Windows service that, when started, launches it?
10 Answers 10
To create a Windows Service from an executable, you can use sc.exe :
You must have quotation marks around the actual exe path, and a space after the binPath= .
Note that it will not work for just any executable: the executable must be a Windows Service (i.e. implement ServiceMain). When registering a non-service executable as a service, you’ll get the following error upon trying to start the service:
Error 1053: The service did not respond to the start or control request in a timely fashion.
There are tools that can create a Windows Service from arbitrary, non-service executables, see the other answers for examples of such tools.
Use NSSM( the non-Sucking Service Manager ) to run a .BAT or any .EXE file as a service.
- Step 1: Download NSSM
- Step 2: Install your sevice with nssm.exe install [serviceName]
- Step 3: This will open a GUI which you will use to locate your executable
Extending (Kevin Tong) answer.
Step 1: Download & Unzip nssm-2.24.zip
Step 2: From command line type:
C:\> nssm.exe install [servicename]
it will open GUI as below (the example is UT2003 server), then simply browse it to: yourapplication.exe
Many existing answers include human intervention at install time. This can be an error-prone process. If you have many executables wanted to be installed as services, the last thing you want to do is to do them manually at install time.
Towards the above described scenario, I created serman, a command line tool to install an executable as a service. All you need to write (and only write once) is a simple service configuration file along with your executable. Run
will install the service. stdout and stderr are all logged. For more info, take a look at the project website.
A working configuration file is very simple, as demonstrated below. But it also has many useful features such as and
these extras prove useful.. need to be executed as an administrator
If your service name has any spaces, enclose in «quotes».
I’ve tested a good product for that: AlwaysUp. Not free but they have a 30 days trial period so you can give it a try.
Same as Sergii Pozharov’s answer, but with a PowerShell cmdlet:
See New-Service for more customization.
This will only work for executables that already implement the Windows Services API.
You can check out my small free utility for service create\edit\delete operations. Here is create example:
Go to Service -> Modify -> Create
Executable file (google drive): [Download]
Probably all your answers are better, but — just to be complete on the choice of options — I wanted to remind about old, similar method used for years:
SrvAny (installed by InstSrv)
I created the cross-platform Service Manager software a few years back so that I could start PHP and other scripting languages as system services on Windows, Mac, and Linux OSes:
Service Manager is a set of precompiled binaries that install and manage a system service on the target OS using nearly identical command-line options (source code also available). Each platform does have subtle differences but the core features are mostly normalized.
If the child process dies, Service Manager automatically restarts it.
Processes that are started with Service Manager should periodically watch for two notification files to handle restart and reload requests but they don’t necessarily have to do that. Service Manager will force restart the child process if it doesn’t respond in a timely fashion to controlled restart/reload requests.
Install a Windows service using a Windows command prompt?
I want to install a Windows service using a Windows command prompt (not the Visual Studio command prompt).
How do I do this?
19 Answers 19
Navigate to the installutil.exe in your .net folder (for .net 4 it’s C:\Windows\Microsoft.NET\Framework\v4.0.30319 for example) and use it to install your service, like this:
Nothing wrong with SC Create command. Just you need to know the correct args :
If the directory’s name has a space like c:\program files\abc 123 , then you must use double quotes around the path.
It makes things much easier if you set up a bat file like following,
e.g. To install a service, create a «myserviceinstaller.bat» and «Run as Administrator«
to uninstall service,
Just add a -u to the installutil command.
Perform the following:
- Start up the command prompt (CMD) with administrator rights.
- Type c:\windows\microsoft.net\framework\v4.0.30319\installutil.exe [your windows service path to exe]
- Press return and that’s that!
It’s important to open with administrator rights otherwise you may find errors that come up that don’t make sense. If you get any, check you’ve opened it with admin rights first!
To open with admin rights, right click ‘Command Prompt’ and select ‘Run as administrator’.
Install Service:-
UnInstall Sevice:-
Create a *.bat file beside of your windows service exe file for installing with the following context:
Create a *.bat file beside of your windows service exe file for uninstalling with the following context:
Run each of bat file as Admin to install or uninstall your windows service.
I must add one more point in this thread. To install/uninstall 64-bit version of assemblies one should use 64-bit version of tool. To install a service, the command should be:
and to uninstall the command should be:
- Run Windows Command Prompt as Administrator
- paste this code: cd C:\Windows\Microsoft.NET\Framework\v4.0.30319\ to go to folder
- edit and run this too: installutil C:\ProjectFolder\bin\Debug\MyProject.exe
Note: To uninstall: installutil /u C:\ProjectFolder\bin\Debug\MyProject.exe
Open Visual studio and select new project by selecting Windows Service template in Windows Desktop tab. Than copy following code into your service_name.cs file.
Right-Click on service_name.cs file and open designer of service. than right-click and select Add Installer . than right-click on serviceProcessInstaller1 and change its property value of Account from User to Local System .
Remove static void main method from Program.cs file. Than save and Build your project.
NOTE: goto bin\Ddebug folder of your project folder. Than open Properties of your service_name.exe file. Than goto Compatibility tab. Than click on Change Settings For All Users .
Select option Run this program as an administrator .
Now, You have to open CommandPromt as Administrator. After open, set directory to where your InstallUtil.exe file is placed. for ex: C:\Windows\Microsoft.NET\Framework64\v4.0.30319 . now write the following command:
Note: -i is for install he service and -u for Unsinstall.
after -i set the write the path where you want to install your service.
now write the command in CommandPromt as follows:
Note: use stop for stop the Service.