我们需要创建一个能够自我更新的Windows服务。
我想到了三个选择,
管理第一项服务的检索,卸载和安装的第二项服务。
使用某些第三方框架(建议欢迎。我相信.NET支持自动更新Windows窗体应用程序,但不支持Windows服务)
使用插件模型,其中服务只是一个包含更新和运行逻辑的shell,服务的业务逻辑包含在可以换出的DLL中。
任何人都能解释一下这个问题的解决方案吗?
由于
答案 0 :(得分:4)
我的一些想法。
1似乎有问题,因为你最终会处理你想要解决的情况,因为在某些时候更新程序需要更新。 3听起来不错但如果“换出”你的意思是在运行时使用一些花哨的反射加载dll我不确定性能是否会成为一个问题。
第四个选项是服务可以生成一个更新过程,允许它在运行之前根据需要更新更新可执行文件。从那里开始编写一个安装应用程序很简单,该服务将在关闭之前生成。
答案 1 :(得分:4)
Google有一个名为Omaha的开源框架,它完全可以完成您的观点1.的描述。它在其管理的应用程序外部,作为计划的Windows任务在后台运行。 Google使用Omaha来自动更新其Windows应用程序,包括Chrome。由于它来自Google,并且安装在每台运行Chrome的Windows计算机上,因此奥马哈功能非常强大。
有一个article online,它更详细地说明了如何使用Omaha来更新Windows服务。它辩称,由于Omaha具有异步特性,因此特别适合服务(相对于GUI应用程序)。
因此,您可以使用奥马哈来完成第2点和第1点的操作。恐怕我不知道你会怎么做3。
答案 2 :(得分:1)
我使用选项1.这些天更新程序进程很少更新。它使用一个XML文件,其中包含从哪里获取文件的详细信息(当前支持SVN,致力于添加NuGet支持)以及放置它们的位置。它还指定哪些是服务,哪些是网站,并指定用于每个项目的服务的名称。
进程轮询源,如果有新版本可用,则将其复制到新版本编号目录,然后更新服务。它还保留每个更新的5个副本,以便在出现问题时轻松回滚。
这是更新程序的核心代码,它停止现有服务,复制文件,然后重新启动它。
if (isService)
{
log.Debug("Stopping service " + project.ServiceName);
var service = GetService(project);
if (service != null &&
service.Status != System.ServiceProcess.ServiceControllerStatus.Stopped && service.Status != System.ServiceProcess.ServiceControllerStatus.StopPending)
{
service.Stop();
}
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped, new TimeSpan(0, 1, 0));
if (service.Status == System.ServiceProcess.ServiceControllerStatus.Stopped)
log.Debug("Service stopped");
else
log.Error("ERROR: Expected Stopped by Service is " + service.Status);
}
log.Debug("Copying files over");
CopyFolder(checkoutDirectory, destinationDirectory);
if (isService)
{
log.Debug("Starting service");
var service = GetService(project);
// Currently it doesn't create services, you need to do that manually
if (service != null)
{
service.Start();
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running, new TimeSpan(0, 1, 0));
if (service.Status == System.ServiceProcess.ServiceControllerStatus.Running)
log.Debug("Service running");
else
log.Error("Service " + service.Status);
}
}