76

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.

Brendan Reynolds
  • 991
  • 2
  • 9
  • 19
  • 8
    I have looked at the 'Create Windows service from executable' question. It does not appear to be relevant to my question, as it is not about Topshelf. – Brendan Reynolds Aug 13 '13 at 10:45
  • 2
    Yes, that is what Topshelf does, and yes, I have researched their documentation. – Brendan Reynolds Aug 13 '13 at 10:54
  • Well what did you find? As apparently you seem to have trouble following their documentation, especially at _"The application is installed and runs, but as a console application, not a Windows service"_. Do you see the service installed in Windows' Services MMC snap-in? – CodeCaster Aug 13 '13 at 10:56
  • 2
    As far as I can tell from the documentation (http://docs.topshelf-project.com/en/latest/index.html) I'm doing what I'm supposed to do. But as it's not working for me - but appears, from my searches, to be working for others - presumably I'm overlooking something. And no, the application does not appear in the Windows Services MMC snap-in. – Brendan Reynolds Aug 13 '13 at 11:04

4 Answers4

90

Run your service.exe install to install the service.

See the Topshelf Command Line Reference documentation for more information.

Travis
  • 10,444
  • 2
  • 28
  • 48
  • 2
    Thank you! My mistake was that I was trying to install the setup.exe created when I published the application, when I should have been installing the servicename.exe file in the bin\release folder! Doh! All working now. – Brendan Reynolds Aug 13 '13 at 11:55
  • This does nothing without some sort of code in the program itself to handle the installation. – computercarguy Oct 25 '19 at 15:56
  • @Travis can you check my latest question I'm having issues with Topshelf installation. Thanks a lot mate – Roxy'Pro Jun 19 '20 at 15:26
39
  1. Start Visual Studio and create a new C# Console-Application
  2. Right click on references and go to manage NuGet-Packages
  3. Download and install Topshelf via NuGet
  4. Paste the Code below into your application and include all imports.
  5. Switch from “Debug” mode to “Release” and build the application.
  6. Run cmd.exe as administrator
  7. Navigate the console to

    .\myConsoleApplication\bin\Release\
    
  8. Run the command

    .\myConsoleApplication.exe install
    
  9. 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");    

            });                                                 
        }
    }
}
Jonas_Hess
  • 1,874
  • 1
  • 22
  • 32
  • can i autostart the service automatically after install ? – mrid May 19 '20 at 17:38
  • @mrid: The install command has various command line options, including configuring the service for autostart, delayed start and manual start. See the TopShelf Command Line Reference for details: http://docs.topshelf-project.com/en/latest/overview/commandline.html – Simon Elms Aug 28 '21 at 02:01
8

Browse to the folder and run the command:

AppName.exe install

You must run your command prompt as an Admin.

Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
Sunny Okoro Awa
  • 523
  • 4
  • 9
3

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.

granadaCoder
  • 26,328
  • 10
  • 113
  • 146