好的......很简单。实际上,我已经在大部分时间内完成了这项工作。然而,有时候,虽然程序似乎不同意,但服务实际上并没有停止。该程序只是停止服务,将文件从一个地方复制到另一个地方,然后启动服务。该服务锁定正在复制的文件,因此必须停止。
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循环中停止/启动,如:
while(count<5){
sc.WaitForStatus(ServiceControllerStatus.Stopped);
count = count+1;
}
但我认为这也可能失败。虽然我的查询可能不正确,但我发现的所有内容都没有完全回答我的问题。运行此代码的应用程序是一个多线程环境(因此锁定)。如果我在失败后重新运行应用程序,它就可以运行。它返回的错误是您在另一个进程中打开的典型&#34;文件&#34;您尝试打开另一个文件时收到的错误。请注意,这是一个远程环境,其中包含我访问的服务和文件,是的,我确实拥有管理员权限,因此UAC不是问题。
所以问题是:在继续之前,我怎么能确定服务已经停止或完全启动?我几乎可以接受任何解决方案。
回复重复问题:
将这一点分开的是,它是我正在访问的远程系统,以便执行此工作。问题指出,重复的问题没有指定或显示远程方案。我会对它进行测试,如果成功,我会将其作为答案发布。然而,在此之前它并不重复。
答案 0 :(得分:0)
两种解决方案:
一个。更新服务代码以刷新其在数据库或文件的开始/结束时的状态。您的程序会读取状态。
B中。您的程序会检查服务线程是否存在。
答案 1 :(得分: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);
}
}
}