2013-02-27 111 views
2

我已经构建了一个Windows服务来监视我们的服务器上的一些设置,我已经开发了不少WinForm和WPF应用程序,但对于Windows服务我是一个绝对的新手,这就是为什么我诉诸于msdn,并按照教程how to create a simple service。现在,我可以安装该服务,并使其运行,但只有当我从微软教程中删减了一些零碎......但我很好奇为什么,当我按照教程,我的服务在启动时得到一个意外的错误。Windows服务 - 在启动时崩溃

经过一些测试,似乎该服务似乎OnStart方法崩溃在SetServiceStatus()

public partial class MyService: ServiceBase 
{ 
    private static ManualResetEvent pause = new ManualResetEvent(false); 

    [DllImport("ADVAPI32.DLL", EntryPoint = "SetServiceStatus")] 
    public static extern bool SetServiceStatus(IntPtr hServiceStatus, SERVICE_STATUS lpServiceStatus); 
    private SERVICE_STATUS myServiceStatus; 

    private Thread workerThread = null; 
    public MyService() 
    { 
     InitializeComponent(); 
     CanPauseAndContinue = true; 
     CanHandleSessionChangeEvent = true; 
     ServiceName = "MyService"; 
    } 
    static void Main() 
    { 
     // Load the service into memory. 
     System.ServiceProcess.ServiceBase.Run(MyService()); 
    } 

    protected override void OnStart(string[] args) 
    { 
     IntPtr handle = this.ServiceHandle; 
     myServiceStatus.currentState = (int)State.SERVICE_START_PENDING; 
     **SetServiceStatus(handle, myServiceStatus);** 
     // Start a separate thread that does the actual work. 
     if ((workerThread == null) || ((workerThread.ThreadState & (System.Threading.ThreadState.Unstarted | System.Threading.ThreadState.Stopped)) != 0)) 
     { 
      workerThread = new Thread(new ThreadStart(ServiceWorkerMethod)); 
      workerThread.Start(); 
     } 
     myServiceStatus.currentState = (int)State.SERVICE_RUNNING; 
     SetServiceStatus(handle, myServiceStatus); 
    } 
} 

现在我的服务似乎运行得很好,当我注释掉SetServiceStatus()线。为什么这会失败?这是一个权利问题还是我完全忽略了这一点?

+2

你有调用'SetServiceStatus'的一些具体原因吗?这不是严格要求,你可能只是摆脱这些电话。 – CodingGorilla 2013-02-27 17:55:34

+1

你可以按照这个简单的教程来做一个简单的Windows服务。所有这些外部电话都不需要您的服务工作。 [http://www.codeproject.com/Articles/14353/Creating-a-Basic-Windows-Service-in-C] – 2013-02-27 19:12:15

+0

那么我没有具体的原因,只是试图跟随msdn,并想知道为什么在地球上它失败了。 – XikiryoX 2013-02-27 22:05:30

回答

4

通常,在使用框架实施托管服务时,您不必调用SetServiceStatus。也就是说,如果你确实叫它,你需要在使用它之前完全初始化SERVICE_STATUS。您目前只设置了状态,但none of the other variables

这是在SetServiceStatus的最佳实践中建议的:“初始化SERVICE_STATUS结构中的所有字段,确保存在有效的检查点并等待未决状态的提示值,并使用合理的等待提示。

+1

的确,他所说的。实施(和响应)事件,例如OnStart(),OnStop()和其他各种电源事件将根据您对这些事件的处理隐式管理您的服务的状态。你不应该需要任何extern /直接访问Win32 API来完成你在这里说明的内容。 – 2013-02-27 18:01:52

+0

所以一般来说,创建一个像这样的托管服务时,我不需要使用SetServiceStatus。如果我这样做...还有一些我需要担心的事情。谢谢,你们在这里的黑暗中散发出一些光芒。干杯。 – XikiryoX 2013-02-27 22:09:56