2016-05-17 71 views
0

好吧...足够简单。实际上,我已经完成了大部分工作。然而,有些时候,虽然该程序似乎不同意,但该服务并未实际停止。该程序只是停止服务,将文件从一个地方复制到另一个地方,然后启动服务。该服务锁定了正在复制的文件,因此必须停止。等待一项服务完全停止/开始继续之前

internal void StopTheService() 
    { 
     Logger.Log("Stopping the service."); 
     lock (myLock) { 
      var sc = new ServiceController() { ServiceName = nameOfService, MachineName = nameOfServerWithService }; 
      sc.Stop(); 
      sc.WaitForStatus(ServiceControllerStatus.Stopped); 
     } 
     Logger.Log("Service stopped."); 
    } 

internal void StartTheService() 
    { 
     Logger.Log("Starting the service."); 
     lock (myLock) { 
      var sc = new ServiceController() { ServiceName = nameOfService, MachineName = nameOfServerWithService }; 
      sc.Start(); 
      sc.WaitForStatus(ServiceControllerStatus.Running); 
     } 
     Logger.Log("Service Started."); 
    } 

此代码工作的大部分,但问题是,当它认为该服务已停止,并移动到下一个步骤,复制,失败。我可以等待它停止/开始在一段时间循环,如:

while(count<5){ 
    sc.WaitForStatus(ServiceControllerStatus.Stopped); 
    count = count+1; 
} 

但我认为这也可能会失败。我发现的所有东西都不在网上,并不完全回答我的问题,尽管我的查询可能不正确。运行此代码的应用程序是多线程环境(因此锁)。如果我在失败后重新运行应用程序,它将起作用。它返回的错误是您尝试打开另一个文件时得到的典型“在另一个进程中打开的文件”错误。请注意,这是一个远程环境,它具有我正在访问的服务和文件,是的,我拥有管理权限,因此UAC不是问题。

所以问题:如何确定服务在继续之前已经停止或开始完成?我几乎可以接受任何解决方案。

在应对重复的问题:

,设置这个与众不同的是,它是我为了完成这项工作正在访问远程系统的事情。作为重复问题记录的问题未指定或显示远程方案。我会测试它,如果它成功,我会张贴它作为答案。但在此之前它不是重复的。

+0

“是,当它认为服务已停止并且移动到下一步时,复制失败。” - 你有调试过吗?我可以看到这是“服务停止,但操作系统排序清理文件处理” - 但没有别的。这听起来像是一个令人讨厌的bug,你可能根本无法解决(而且我从来没有经历过)。 – TomTom

+0

@Richard Barker我一直有这个确切的问题和http://stackoverflow.com/a/1597244/60188很好地解决了一切。 –

+0

@AntonGogolev哇这是一个旧的。而当我输入完全相同的问题名称时,Stackoverflow没有找到它。 –

回答

0

好吧,重复问题的答案大部分是正确的答案。该答案(stackoverflow.com/a/1597244/60188)上的代码大部分都是正确的,但远程机器部件除外。

public void StopServiceAndWaitForExit() 
    { 

     using (var controller = new ServiceController(nameOfService, nameOfServerWithService)) 
     { 
      var ssp = new SERVICE_STATUS_PROCESS(); 
      int ignored; 

      if (!QueryServiceStatusEx(controller.ServiceHandle.DangerousGetHandle(), SC_STATUS_PROCESS_INFO, ref ssp, Marshal.SizeOf(ssp), out ignored)) 
       throw new Exception("Couldn't obtain service process information."); 

      if (ssp.dwServiceType != SERVICE_WIN32_OWN_PROCESS) 
       throw new Exception("Can't wait for the service's hosting process to exit because there may be multiple services in the process (dwServiceType is not SERVICE_WIN32_OWN_PROCESS"); 

      if ((ssp.dwServiceFlags & SERVICE_RUNS_IN_SYSTEM_PROCESS) != 0) 
       throw new Exception("Can't wait for the service's hosting process to exit because the hosting process is a critical system process that will not exit (SERVICE_RUNS_IN_SYSTEM_PROCESS flag set)"); 

      if (ssp.dwProcessId == 0) 
       throw new Exception("Can't wait for the service's hosting process to exit because the process ID is not known."); 

      using (Process process = Process.GetProcessById(ssp.dwProcessId, nameOfServerWithService)) 
      { 
       var threadData = new ProcessWaitForExitData(); 

       threadData.Process = process; 

       var processWaitForExitThread = new Thread(ProcessWaitForExitThreadProc); 

       processWaitForExitThread.IsBackground = Thread.CurrentThread.IsBackground; 
       processWaitForExitThread.Start(threadData); 

       controller.Stop(); 

       lock (threadData.Sync) 
        while (!threadData.HasExited) 
         Monitor.Wait(threadData.Sync); 
      } 
     } 
    } 
0

两个解决方案:

A.更新服务代码刷新其在开始/结束状态,数据库或文件。你的程序读取状态。

B.您的程序检查服务线程是否存在。

+0

A需要更新服务 - 我希望避免这一点,但它应该归结为它我会。 B可能是可能的,但前提是我可以从远程机器上做到这一点。 –

相关问题