[.net] 설치 직후 .NET Windows 서비스를 시작하는 방법은 무엇입니까?

service.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.



답변

InstallUtil 프로세스에서 발생한 이벤트에 대한 응답으로 서비스 실행 파일 내에서이 모든 작업을 수행 할 수 있습니다. ServiceController 클래스를 사용하여 서비스를 시작하려면 OnAfterInstall 이벤트를 재정의하십시오.

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


답변

여기 에 C #에서 Windows 서비스를 만드는 단계별 절차를 게시했습니다 . 적어도이 시점까지 들리는 것 같고 이제 서비스가 설치된 후 시작하는 방법이 궁금합니다. StartType 속성을 Automatic으로 설정하면 시스템을 재부팅 한 후 서비스가 자동으로 시작되지만 설치 후 서비스가 자동으로 시작되지는 않습니다.

원래 어디서 찾았는지 기억 나지 않지만 (아마도 Marc Gravell?) 실제로 서비스 자체를 실행하여 서비스를 설치하고 시작할 수있는 솔루션을 온라인에서 찾았습니다. 다음은 단계별입니다.

  1. 구조 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();
            }
        }
    }
    
  2. 다음은 지원 코드입니다.

    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;
    }
    
  3. 지원 코드 계속 …

    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;
            }
        }
    }
    
  4. 이 시점에서 대상 컴퓨터에 서비스를 설치 한 후 -install명령 줄 인수를 사용 하여 명령 줄 (일반 애플리케이션과 마찬가지로)에서 서비스를 실행하여 서비스 를 설치하고 시작합니다.

내가 모든 것을 다룬 것 같지만 이것이 작동하지 않는 경우 알려 주시면 답변을 업데이트 할 수 있습니다.


답변

비주얼 스튜디오

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>


답변

EXE의 구성 요소 이름 또는 배치 (sc start)를 소스로 사용하여 MSI의 ‘ExecuteImmediate’시퀀스 끝에 사용자 지정 작업을 추가해야합니다. Visual Studio에서는 이것이 가능하지 않다고 생각합니다. 실제 MSI 저작 도구를 사용해야 할 수도 있습니다.


답변

설치 후 바로 시작하기 위해 installutil 다음에 sc start를 사용하여 배치 파일을 생성합니다.

이상적은 아니지만 작동합니다 ….


답변

.NET ServiceController 클래스를 사용하여 시작하거나 명령 줄 명령을 실행하여 시작 — “net start servicename”. 어느 쪽이든 작동합니다.


답변

ScottTx의 답변에 추가하려면 Microsoft 방식으로 수행하는 경우 서비스를 시작하는 실제 코드는 다음과 같습니다. (예 : 설치 프로젝트 사용 등).

(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 디자이너로 이동합니다. ServiceInstaller1 컨트롤을 클릭합니다. 이벤트 아래의 속성 창으로 이동하면 AfterInstall 이벤트를 찾을 수 있습니다.

참고 : 위 코드를 ServiceProcessInstaller1의 AfterInstall 이벤트 아래에 두지 마십시오. 경험에서 오는 것은 작동하지 않습니다. 🙂