31

We need to create a windows service that has the ability to self update.

Three options spring to mind,

  1. a second service that manages the retrieval, uninstallation and installation of the first service.

  2. Use of some third party framework (suggestions welcome. I believe .NET supports automatic updating for windows forms apps, but not windows services)

  3. Use of a plugin model, whereby the service is merely a shell containing the updating and running logic, and the business logic of the service is contained in a DLL that can be swapped out.

Can anyone shed some light on the solution to this problem?

Thanks

4

3 回答 3

5

谷歌有一个名为Omaha的开源框架,它完全符合您的第 1 点所描述的内容。它在其管理的应用程序之外作为计划的 Windows 任务在后台运行。Google 使用 Omaha 自动更新他们的 Windows 应用程序,包括 Chrome。因为它来自 Google,并且因为它安装在每台运行 Chrome 的 Windows 机器上,所以 Omaha 非常强大。

网上有一篇文章更详细地解释了如何使用 Omaha 来更新 Windows 服务。它认为 Omaha 非常适合服务(相对于 GUI 应用程序),因为它具有异步特性。

因此,您可以使用 Omaha 来完成您的第 2 点和第 1 点。恐怕我不知道你会怎么做 3。

于 2020-10-27T08:03:29.407 回答
4

只是我的一些想法。

1 似乎有问题,因为您最终要处理您要解决的情况,因为在某些时候更新程序需要更新。3 听起来不错,但如果“换出”是指在运行时使用一些花哨的反射来加载 dll,我不确定性能是否会成为问题。

还有第四个选项,服务可以生成一个更新进程,如果需要,它可以在运行之前更新更新可执行文件。从那里开始,编写一个安装应用程序是一件简单的事情,该服务将在关闭之前产生。

于 2009-10-22T16:03:53.953 回答
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);
    }
}
于 2011-09-17T20:08:08.913 回答