如何进行 windows 服务自我更新?

how to have a windows service self update?

我能找到的关于这个主题的所有解决方案都非常古老,其中 none 似乎可以回答我的问题...

我正在尝试创建一个 windows 可以自我更新(或通过某些外部触发器自动更新)的服务。过去,我创建了一个与 InstallShield 一起安装的 windows 服务,我们能够通过让该服务向本地计算机写入批处理脚本然后 运行 批处理脚本,它将停止服务,用新文件覆盖服务可执行文件和其他文件,然后重新启动服务。这出人意料地奏效了。

但是,我已将服务更新为使用 InstallUtil.exe,此自动更新脚本不再有效...我认为这与 InstallShield 处理服务安装的方式以及 InstallUtil 的处理方式有关。 .. 但我只能猜测,因为我不完全理解每个人对注册表做了什么。

因为我不能只覆盖文件并使用 InstallUtil 方法重新启动服务,我想我会写一个批处理脚本 运行s sc.exe 来停止服务,卸载它完全,写入新文件,安装新服务文件,然后启动它...不幸的是,我似乎无法从 windows 服务自动获取 sc.exe 到 运行因为它需要管理员权限...我试图使用此代码段强制它自我提升为管理员,但它似乎不能作为服务工作(如果我从命令行 运行 它工作正常作为一项服务)

if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)

有谁知道如何让 windows 服务自行更新?如果 .NET Core 中有某种我不知道的自我更新方法,我可以考虑更新到 .NET Core Worker 服务......非常感谢任何想法......真的不应该这么难完成...

作为参考,这是我当前正在使用的批处理脚本(忽略奇怪的变量,例如我正在动态替换其中的一些变量,它在手动启动时效果很好,只是在服务尝试 运行它):

@echo off
setlocal enableextensions enabledelayedexpansion


::make sure to run whole script as admin (this restarts scripts as admin if not already in admin mode)
if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)
pushd %networkDirectory%

::stop running service
for /F "tokens=3 delims=: " %%H in ('sc query %serviceName% ^| findstr "        STATE"') do (
    if /I "%%H" NEQ "STOPPED" (
        net stop %serviceName%
        if errorlevel 1 goto :stop
    )

    ::delete existing service after stopping
    sc delete %serviceName%
)

:: install updated service files
set "releaseDir=%networkDirectory%\Release"
set "programFilesCopyDir=%ProgramFiles%\{_companyDirectory}\%serviceName%\Release"

:: copy service Release dir to local system program files
xcopy "%releaseDir%" "%programFilesCopyDir%" /S /Y /Q

::execute the install
pushd "%programFilesCopyDir%"
CALL %serviceName%.exe --install

::start service
sc start %serviceName%

对于任何其他试图完成这个但偶然发现的人...我最终找到了解决方案。我使用上面问题中发布的相同脚本,但我编写了代码以使用 Windows Task Scheduler 设置计划任务。计划任务将上述脚本作为一次性计划任务运行。这很有魅力。

我使用这个 NuGet 包来编写我需要的任务计划程序代码: https://www.nuget.org/packages/TaskScheduler/2.8.20?_src=template