如何从exe服务运行exe并在exe进程退出时停止服务?

时间:2010-09-15 15:22:20

标签: c# multithreading windows-services

我是使用Windows服务的完全初学者。我有一个基本的骨架为服务工作,我目前正在这样做:

protected override void OnStart(string[] args)
    {
        base.OnStart(args);
        Process.Start(@"someProcess.exe");
    }

只是在程序开始时启动exe。

但是,当进程从exe退出开始时,我想让服务停止。 我很确定我需要做一些线程(我也是初学者),但我不确定这是如何工作的总体轮廓,也不确定从内部停止进程的具体方法。 你能帮我解决这个问题的一般过程(即从OnStart开始一个线程,那么......?)?谢谢。

3 个答案:

答案 0 :(得分:11)

您可以使用BackgroundWorker进行线程处理,使用Process.WaitForExit()等待流程终止,直到您停止服务为止。

你应该做一些线程是正确的,在OnStart中做大量的工作可能会导致在启动服务时无法从Windows正确启动的错误。

protected override void OnStart(string[] args)
{

    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += new DoWorkEventHandler(bw_DoWork);
    bw.RunWorkerAsync();
}

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    Process p = new Process();
    p.StartInfo = new ProcessStartInfo("file.exe");
    p.Start();
    p.WaitForExit();
    base.Stop();
}

修改 您可能还想将Process p移动到类成员并在OnStop中停止该过程,以确保如果exe变得混乱,您可以再次停止服务。

protected override void OnStop()
{
    p.Kill();
}

答案 1 :(得分:2)

您必须使用ServiceController来执行此操作,它具有Stop方法。确保您的服务将CanStop属性设置为true。

答案 2 :(得分:1)

someProcess.exe应该 someLogic 来停止呼叫服务;)

使用ServiceController类。

// Toggle the Telnet service - 
// If it is started (running, paused, etc), stop the service.
// If it is stopped, start the service.
ServiceController sc = new ServiceController("Telnet");
Console.WriteLine("The Telnet service status is currently set to {0}", 
                  sc.Status.ToString());

if  ((sc.Status.Equals(ServiceControllerStatus.Stopped)) ||
     (sc.Status.Equals(ServiceControllerStatus.StopPending)))
{
   // Start the service if the current status is stopped.

   Console.WriteLine("Starting the Telnet service...");
   sc.Start();
}  
else
{
   // Stop the service if its status is not set to "Stopped".

   Console.WriteLine("Stopping the Telnet service...");
   sc.Stop();
}  

// Refresh and display the current service status.
sc.Refresh();
Console.WriteLine("The Telnet service status is now set to {0}.", 
                   sc.Status.ToString());

代码来自上面链接的页面。