Как запустить службу .NET Windows сразу после установки?

Помимо сервиса .StartType = ServiceStartMode.Automatic моя служба не запускается после установки

Решение

Вставьте этот код в свой ProjectInstaller

protected override void OnAfterInstall(System.Collections.IDictionary savedState)
{
    base.OnAfterInstall(savedState);
    using (var serviceController = new ServiceController(this.serviceInstaller1.ServiceName, Environment.MachineName))
        serviceController.Start();
}

Благодаря ScottTx и Francis B.

Ответ 1

Вы можете сделать все это из исполняемого файла службы в ответ на события, запущенные из процесса InstallUtil. Переопределите событие OnAfterInstall, чтобы использовать класс ServiceController для запуска службы.

http://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceinstaller.aspx

Ответ 2

Я опубликовал пошаговую процедуру создания службы Windows на С# здесь. Похоже, вы по крайней мере до этого момента, и теперь вам интересно, как запустить службу после ее установки. Установка свойства StartType на "Автоматически" приведет к тому, что служба начнет автоматически после перезагрузки вашей системы, но она не будет (как вы обнаружили) автоматически запускать ваш сервис после установки.

Я не помню, откуда я его нашел (возможно, Марк Гравелл?), но я нашел решение в Интернете, которое позволяет вам устанавливать и запускать свою службу, фактически запустив свое обслуживание. Здесь шаг за шагом:

  • Структурируйте функцию Main() вашего сервиса следующим образом:

    static void Main(string[] args)
    {
        if (args.Length == 0) {
            // Run your service normally.
            ServiceBase[] ServicesToRun = new ServiceBase[] {new YourService()};
            ServiceBase.Run(ServicesToRun);
        } else if (args.Length == 1) {
            switch (args[0]) {
                case "-install":
                    InstallService();
                    StartService();
                    break;
                case "-uninstall":
                    StopService();
                    UninstallService();
                    break;
                default:
                    throw new NotImplementedException();
            }
        }
    }
    
  • Вот код поддержки:

    using System.Collections;
    using System.Configuration.Install;
    using System.ServiceProcess;
    
    private static bool IsInstalled()
    {
        using (ServiceController controller = 
            new ServiceController("YourServiceName")) {
            try {
                ServiceControllerStatus status = controller.Status;
            } catch {
                return false;
            }
            return true;
        }
    }
    
    private static bool IsRunning()
    {
        using (ServiceController controller = 
            new ServiceController("YourServiceName")) {
            if (!IsInstalled()) return false;
            return (controller.Status == ServiceControllerStatus.Running);
        }
    }
    
    private static AssemblyInstaller GetInstaller()
    {
        AssemblyInstaller installer = new AssemblyInstaller(
            typeof(YourServiceType).Assembly, null);
        installer.UseNewContext = true;
        return installer;
    }
    
  • Продолжение с поддерживающим кодом...

    private static void InstallService()
    {
        if (IsInstalled()) return;
    
        try {
            using (AssemblyInstaller installer = GetInstaller()) {
                IDictionary state = new Hashtable();
                try {
                    installer.Install(state);
                    installer.Commit(state);
                } catch {
                    try {
                        installer.Rollback(state);
                    } catch { }
                    throw;
                }
            }
        } catch {
            throw;
        }
    }
    
    private static void UninstallService()
    {
        if ( !IsInstalled() ) return;
        try {
            using ( AssemblyInstaller installer = GetInstaller() ) {
                IDictionary state = new Hashtable();
                try {
                    installer.Uninstall( state );
                } catch {
                    throw;
                }
            }
        } catch {
            throw;
        }
    }
    
    private static void StartService()
    {
        if ( !IsInstalled() ) return;
    
        using (ServiceController controller = 
            new ServiceController("YourServiceName")) {
            try {
                if ( controller.Status != ServiceControllerStatus.Running ) {
                    controller.Start();
                    controller.WaitForStatus( ServiceControllerStatus.Running, 
                        TimeSpan.FromSeconds( 10 ) );
                }
            } catch {
                throw;
            }
        }
    }
    
    private static void StopService()
    {
        if ( !IsInstalled() ) return;
        using ( ServiceController controller = 
            new ServiceController("YourServiceName")) {
            try {
                if ( controller.Status != ServiceControllerStatus.Stopped ) {
                    controller.Stop();
                    controller.WaitForStatus( ServiceControllerStatus.Stopped, 
                         TimeSpan.FromSeconds( 10 ) );
                }
            } catch {
                throw;
            }
        }
    }
    
  • На этом этапе после установки службы на целевой машине просто запустите свою службу из командной строки (как и любое обычное приложение) с аргументом командной строки -install для установки и запуска вашей службы.

Я думаю, что я все рассмотрел, но если вы обнаружите, что это не сработает, сообщите мне, чтобы я мог обновить ответ.

Ответ 3

Visual Studio

Если вы создаете проект установки с помощью VS, вы можете создать настраиваемое действие, которое вызвало метод .NET для запуска службы. Но на самом деле не рекомендуется использовать управляемые пользовательские действия в MSI. Смотрите страница.

ServiceController controller  = new ServiceController();
controller.MachineName = "";//The machine where the service is installed;
controller.ServiceName = "";//The name of your service installed in Windows Services;
controller.Start();

InstallShield или Wise

Если вы используете InstallShield или Wise, эти приложения предоставляют возможность запуска службы. Например, с помощью Wise вам нужно добавить действие управления сервисом. В этом действии вы указываете, хотите ли вы запустить или остановить службу.

Wix

Используя Wix, вам нужно добавить следующий код xml под компонент вашей службы. Для получения дополнительной информации об этом вы можете проверить эту страницу.

<ServiceInstall 
    Id="ServiceInstaller"  
    Type="ownProcess"  
    Vital="yes"  
    Name=""  
    DisplayName=""  
    Description=""  
    Start="auto"  
    Account="LocalSystem"   
    ErrorControl="ignore"   
    Interactive="no">  
        <ServiceDependency Id="????"/> ///Add any dependancy to your service  
</ServiceInstall>

Ответ 4

Вам нужно добавить пользовательское действие в конец последовательности "ExecuteImmediate" в MSI, используя в качестве источника имя компонента EXE или пакет (sc start). Я не думаю, что это можно сделать с помощью Visual Studio, вам, возможно, придется использовать для этого настоящий инструмент для создания MSI.

Ответ 5

Чтобы запустить его сразу после установки, я создаю пакетный файл с installutil, за которым следует sc start

Это не идеальный, но он работает....

Ответ 6

Используйте класс .NET ServiceController, чтобы запустить его, или выпустите команду командной строки, чтобы запустить его - "net start servicename". В любом случае работает.

Ответ 7

Чтобы добавить к ответу ScottTx, вот фактический код для запуска службы, если вы делаете это путь Microsoft (то есть используя Setup project и т.д.)

(извините код VB.net, но это то, что я застрял)

Private Sub ServiceInstaller1_AfterInstall(ByVal sender As System.Object, ByVal e As System.Configuration.Install.InstallEventArgs) Handles ServiceInstaller1.AfterInstall
    Dim sc As New ServiceController()
    sc.ServiceName = ServiceInstaller1.ServiceName

    If sc.Status = ServiceControllerStatus.Stopped Then
        Try
            ' Start the service, and wait until its status is "Running".
            sc.Start()
            sc.WaitForStatus(ServiceControllerStatus.Running)

            ' TODO: log status of service here: sc.Status
        Catch ex As Exception
            ' TODO: log an error here: "Could not start service: ex.Message"
            Throw
        End Try
    End If
End Sub

Чтобы создать вышеупомянутый обработчик событий, перейдите в конструктор ProjectInstaller, где находятся 2 элемента управления. Нажмите на элемент ServiceInstaller1. Перейдите в окно свойств событий и там вы увидите событие AfterInstall.

Примечание. Не помещайте вышеуказанный код в событие AfterInstall для ServiceProcessInstaller1. Это не сработает, исходя из опыта.:)

Ответ 8

Самое легкое решение найдено здесь install-windows-service-without-installutil-exe by @Hoàng Long

@echo OFF
echo Stopping old service version...
net stop "[YOUR SERVICE NAME]"
echo Uninstalling old service version...
sc delete "[YOUR SERVICE NAME]"

echo Installing service...
rem DO NOT remove the space after "binpath="!
sc create "[YOUR SERVICE NAME]" binpath= "[PATH_TO_YOUR_SERVICE_EXE]" start= auto
echo Starting server complete
pause