我创建了一个应用程序来更新一个Windows服务应用程序(我也创建了)。这个“更新器”应用程序很有魅力,但前提是Windows服务已经停止。
更新程序应用程序的操作顺序如下:
ServiceController
对象MyService.Stop()
(如果它尚未处于ServiceControllerStatus.Stopped
状态)MyService.WaitForStatus()
MyService.Clos()
MyService.Start()
MyService.Clos()
如果服务已经停止,那么这确实有效。但是,如果服务之前正在运行,更新程序应用程序将停止服务并继续到步骤5。此时,我将得到一条错误消息,说我无法重写。dll文件,因为其他进程正在使用这些文件。
起初,我认为是我自己的更新程序应用程序通过ServiceController
对象保持对服务的引用,这时我添加了第4步,这并没有改变任何事情。
如果我运行更新程序应用程序两次,第一次它会停止更新程序并在更新。dll文件时失败。然后当它第二次注意到它已经停止并尝试更新。dll文件时,它就会全部工作。更新service.dll并启动服务。
private static bool ServiceCommand(string serviceName, bool startService, TimeSpan timeout)
{
if (!GetServiceObject(serviceName, out ServiceController service)) return false;
try
{
// First, check to make sure it's not already started or stopped
if (service.Status == (startService ? ServiceControllerStatus.Running : ServiceControllerStatus.Stopped))
{
return true;
}
ServiceControllerStatus myTargetStatus;
if (startService)
{
service.Start();
myTargetStatus = ServiceControllerStatus.Running;
}
else
{
service.Stop();
myTargetStatus = ServiceControllerStatus.Stopped;
}
// Wait for the target status
service.WaitForStatus(myTargetStatus, timeout);
}
catch (Exception e)
{
Logger.Log("Unable to " + (startService ? "start" : "stop") + " service '" + service.ServiceName + "': " + e.Message);
return false;
}
finally
{
if (service != null) service.Close();
}
return true;
}
我相信这就是问题所在。在第5步中,我所做的只是一个file.copy()
,其中override参数设置为true。这就是我得到错误消息进程不能访问文件“”,因为另一个进程正在使用它。
任何帮助或投入都是非常感激的!谢啦!
可执行文件可以向服务控制管理器报告服务已停止,但可执行文件可以继续运行一段时间,例如清理工作或让后台线程完成其工作。它不应该这样做,在这种情况下它应该请求更多的关机时间,但这可能就是正在发生的事情。
因此,要么修复您的服务,使其可执行文件在报告服务已停止状态后立即停止,要么等待可执行文件停止后再复制文件。
另请参见ServiceController.stop()后服务未完全停止,windows服务等待处理停止请求的最长时间是多少以及如何请求额外时间。