c# - net - register windows service command line



如何在.NET中以編程方式重新啟動Windows服務 (6)

ServiceController類使用的示例

private void RestartWindowsService(string serviceName)
{
    ServiceController serviceController = new ServiceController(serviceName);
    try
    {
        if ((serviceController.Status.Equals(ServiceControllerStatus.Running)) || (serviceController.Status.Equals(ServiceControllerStatus.StartPending)))
        {
            serviceController.Stop();
        }
        serviceController.WaitForStatus(ServiceControllerStatus.Stopped);
        serviceController.Start();
        serviceController.WaitForStatus(ServiceControllerStatus.Running);
    }
    catch
    {
        ShowMsg(AppTexts.Information, AppTexts.SystematicError, MessageBox.Icon.WARNING);
    }
}

如何在.NET中以編程方式重新啟動Windows服務?
此外,我需要在服務重啟完成後執行操作。


Answer #1

本文使用ServiceController類編寫啟動,停止和重新啟動Windows服務的方法; 可能值得一看。

文章中的片段(“重新啟動服務”方法):

public static void RestartService(string serviceName, int timeoutMilliseconds)
{
  ServiceController service = new ServiceController(serviceName);
  try
  {
    int millisec1 = Environment.TickCount;
    TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);

    service.Stop();
    service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);

    // count the rest of the timeout
    int millisec2 = Environment.TickCount;
    timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2-millisec1));

    service.Start();
    service.WaitForStatus(ServiceControllerStatus.Running, timeout);
  }
  catch
  {
    // ...
  }
}

Answer #2

您也可以調用net命令來執行此操作。 例:

System.Diagnostics.Process.Start("net", "stop IISAdmin");
System.Diagnostics.Process.Start("net", "start IISAdmin");

Answer #3

看一下ServiceController類。

要執行重新啟動服務時需要執行的操作,我想您應該自己在服務中執行此操作(如果它是您自己的服務)。
如果您無權訪問服務源,那​​麼您可以使用ServiceControllerWaitForStatus方法。


Answer #4

調用Environment.Exit ,錯誤代碼大於0,這似乎是合適的,然後在安裝時我們將服務配置為在出錯時重啟。

Environment.Exit(1);

我在我的服務中做了同樣的事情。 它工作正常。


Answer #5

這個答案是基於@Donut答案(這個問題的最高投票答案),但有一些修改。

  1. 每次使用後都要處理ServiceController類,因為它實現了IDisposable接口。
  2. 減少方法的參數:不需要為每個方法傳遞serviceName參數,我們可以在構造函數中設置它,並且每個其他方法將使用該服務名稱。
    這也是更友好的OOP。
  3. 以此類可用作組件的方式處理catch異常。
  4. 從每個方法中刪除timeoutMilliseconds參數。
  5. 添加兩個新方法StartOrRestartStopServiceIfRunning ,它們可以被視為其他基本方法的包裝器。這些方法的目的只是為了避免異常,如註釋中所述。

這是班級

public class WindowsServiceController
{
    private string serviceName;

    public WindowsServiceController(string serviceName)
    {
        this.serviceName = serviceName;
    }

    // this method will throw an exception if the service is NOT in Running status.
    public void RestartService()
    {
        using (ServiceController service = new ServiceController(serviceName))
        {
            try
            {
                service.Stop();
                service.WaitForStatus(ServiceControllerStatus.Stopped);

                service.Start();
                service.WaitForStatus(ServiceControllerStatus.Running);
            }
            catch (Exception ex)
            {
                throw new Exception($"Can not restart the Windows Service {serviceName}", ex);
            }
        }
    }

    // this method will throw an exception if the service is NOT in Running status.
    public void StopService()
    {
        using (ServiceController service = new ServiceController(serviceName))
        {
            try
            {
                service.Stop();
                service.WaitForStatus(ServiceControllerStatus.Stopped);
            }
            catch (Exception ex)
            {
                throw new Exception($"Can not Stop the Windows Service [{serviceName}]", ex);
            }
        }
    }

    // this method will throw an exception if the service is NOT in Stopped status.
    public void StartService()
    {
        using (ServiceController service = new ServiceController(serviceName))
        {
            try
            {
                service.Start();
                service.WaitForStatus(ServiceControllerStatus.Running);
            }
            catch (Exception ex)
            {
                throw new Exception($"Can not Start the Windows Service [{serviceName}]", ex);
            }
        }
    }

    // if service running then restart the service if the service is stopped then start it.
    // this method will not throw an exception.
    public void StartOrRestart()
    {
        if (IsRunningStatus)
            RestartService();
        else if (IsStoppedStatus)
            StartService();
    }

    // stop the service if it is running. if it is already stopped then do nothing.
    // this method will not throw an exception if the service is in Stopped status.
    public void StopServiceIfRunning()
    {
        using (ServiceController service = new ServiceController(serviceName))
        {
            try
            {
                if (!IsRunningStatus)
                    return;

                service.Stop();
                service.WaitForStatus(ServiceControllerStatus.Stopped);
            }
            catch (Exception ex)
            {
                throw new Exception($"Can not Stop the Windows Service [{serviceName}]", ex);
            }
        }
    }

    public bool IsRunningStatus => Status == ServiceControllerStatus.Running;

    public bool IsStoppedStatus => Status == ServiceControllerStatus.Stopped;

    public ServiceControllerStatus Status
    {
        get
        {
            using (ServiceController service = new ServiceController(serviceName))
            {
                return service.Status;
            }
        }
    }
}




windows-services