Using Visual Studio Express 2012, I've created a console application using Topshelf (Version 3.1.107.0). The application works as a console application, but I can't figure out how to install it as a service. I've published the project from within Visual Studio (Build, Publish), started a command prompt as Administrator, navigated to the folder where the application was published, and run setup.exe -install from the command prompt. The application is installed and runs, but as a console application, not a Windows service. What am I missing here?
For those who may not be familiar with Topshelf, it is a Windows Service framework for .Net and is supposed to facilitate the scenario I describe above - develop and debug as a console application, deploy as a Windows Service. See the documentation at http://docs.topshelf-project.com/en/latest/index.html.
Run your service.exe install
to install the service.
See the Topshelf Command Line Reference documentation for more information.
- Start Visual Studio and create a new C# Console-Application
- Right click on references and go to manage NuGet-Packages
- Download and install Topshelf via NuGet
- Paste the Code below into your application and include all imports.
- Switch from “Debug” mode to “Release” and build the application.
- Run
cmd.exe
as administrator
Navigate the console to
.\myConsoleApplication\bin\Release\
Run the command
.\myConsoleApplication.exe install
Run the command
.\myConsoleApplication.exe start
Code:
using System;
using System.Threading;
using Topshelf;
using Topshelf.Runtime;
namespace MyConsoleApplication
{
public class MyService
{
public MyService(HostSettings settings)
{
}
private SemaphoreSlim _semaphoreToRequestStop;
private Thread _thread;
public void Start()
{
_semaphoreToRequestStop = new SemaphoreSlim(0);
_thread = new Thread(DoWork);
_thread.Start();
}
public void Stop()
{
_semaphoreToRequestStop.Release();
_thread.Join();
}
private void DoWork()
{
while (true)
{
Console.WriteLine("doing work..");
if (_semaphoreToRequestStop.Wait(500))
{
Console.WriteLine("Stopped");
break;
}
}
}
}
public class Program
{
public static void Main()
{
HostFactory.Run(x =>
{
x.StartAutomatically(); // Start the service automatically
x.EnableServiceRecovery(rc =>
{
rc.RestartService(1); // restart the service after 1 minute
});
x.Service<MyService>(s =>
{
s.ConstructUsing(hostSettings => new MyService(hostSettings));
s.WhenStarted(tc => tc.Start());
s.WhenStopped(tc => tc.Stop());
});
x.RunAsLocalSystem();
x.SetDescription("MyDescription");
x.SetDisplayName("MyDisplayName");
x.SetServiceName("MyServiceName");
});
}
}
}
Browse to the folder and run the command:
AppName.exe install
You must run your command prompt as an Admin.
So this is an old question, but I want to add some command line options.
MyTopShelfImplementation.exe install -servicename "MyServiceName"
-displayname "My Display Name" --autostart start
.
--autostart
is for when windows reboots.
start
is for starting the service IMMEDIATELY after you install it
Now, the "names" you can also specify in code
HostFactory.Run(x =>
{
////x.SetDescription("My Description");
x.SetDisplayName("My Display Name");
x.SetServiceName("My Service Name");
////x.SetInstanceName("My Instance");
So if the .exe runs as console app (or as windows service) may be some combination of setting these values in code and/or passing them in via the command line.
I would expect if you did not set the "names" in code AND you did not pass the "names" in by command line args, then you'll get console behavior.