如何让Windows服务更新自己

时间:2016-03-08 16:46:13

标签: c# windows-services automatic-updates

我正在开发一个将作为Windows服务运行的应用程序,并且我试图让它自动更新。

我目前的方法是执行powershell脚本,该脚本将停止服务,运行msi安装程序,然后重新启动服务。

这是powershell脚本此时的样子

Start-Sleep -s 10
Write-Host "update start"
Stop-Service ServiceName1
msiexec /i c:\ProgramData\ProgramName\Install\ServiceName.Setup.msi /passive /l*v C:\ProgramData\ProgramName\Install\log.txt | Out-Null
Start-Service ServiceName1
Write-Host "update finished"

这就是我从应用

运行它的方式
Process.Start("Powershell", @"C:\ProgramData\ProgramName\Install\UpdateApp.ps1");

服务停止并重新启动会发生什么,但它不会更新。就好像msi永远不会运行一样。日志文件甚至不会出现。

当我从提升的命令提示符运行服务作为命令行应用程序时,它按预期工作并且应用程序得到更新,因此我的当前理论是该服务不运行具有管理员权限的powershell脚本。

Other questions suggest that I set up the log on settings for the service to use an administrator account,所以我将服务设置为以我当前登录的帐户运行,该帐户能够打开提升的命令提示符和/或手动运行安装程序,但这样做没有&#39改变任何事情。

有没有办法做我想做的事情?

我目前没有承诺任何特定的自动更新策略,但我知道我希望此服务能够自行更新。因此,如果我做了一些完全错误的事情,我会100%开放尝试不同的方法。

更新

我进行了以下更改以记录msiexecc的错误和输出

Try{
    c:\windows\system32\msiexec.exe /i c:\ProgramData\ProgramName\Install\ServiceName.msi /passive /l*v C:\ProgramData\ProgramName\Install\log.txt | Out-File -filepath C:\ProgramData\ProgramName\Install\output.txt
}
Catch {
    $_ | Out-File C:\ProgramData\ProgramName\Install\errors.txt -Append
}

运行该脚本后,我发现以下错误:

  

术语' msiexec'不被识别为cmdlet,函数,脚本文件或可操作程序的名称。

1 个答案:

答案 0 :(得分:1)

看来msiexec的来电实际上并不是c:\windows\system32\msiexec.exe

根据this question,似乎Powershell不使用标准的PATH环境变量,而是有自己的方案,这可能在系统服务的上下文中没有按预期工作。

正如您所说,最简单的分辨率是指定完整路径,可能是c:\windows\system32\msiexec.exe

但是,在生产中,避免使用硬编码路径可能是明智之举,因为您可能会遇到本地化,操作系统更改等问题。您可以使用服务中的SearchPath或.NET等效项,并实时写出Powershell脚本或将路径作为命令行选项传递给msiexec,或者可能是明智的Powershell解决方案。