.net 正在查找SC.exe实用程序的API,以及关于自我更新Windows服务的建议

.net 正在查找SC.exe实用程序的API,以及关于自我更新Windows服务的建议,.net,windows-services,self-updating,.net,Windows Services,Self Updating,我们已经构建了一个运行在客户端机器上的Windows服务,它偶尔会下载自己的较新版本,然后执行自我更新:安装新服务,启动新服务,停止旧服务,最后将其删除。该服务无法直接停止自身并执行其他操作,因此它会旋转另一个可执行文件,执行部分工作。要做到这一点是很棘手的,当使用较新的.Net框架构建较新的服务时(例如最近从.Net 2.0切换到.Net 4.0),这一点尤其糟糕。问题是.NET2.0库无法在.NET4.0服务上运行 现在,一种方法是让旧版本的服务附带一个新版本的帮助程序,但是。。。如果它的行

我们已经构建了一个运行在客户端机器上的Windows服务,它偶尔会下载自己的较新版本,然后执行自我更新:安装新服务,启动新服务,停止旧服务,最后将其删除。该服务无法直接停止自身并执行其他操作,因此它会旋转另一个可执行文件,执行部分工作。要做到这一点是很棘手的,当使用较新的.Net框架构建较新的服务时(例如最近从.Net 2.0切换到.Net 4.0),这一点尤其糟糕。问题是.NET2.0库无法在.NET4.0服务上运行

现在,一种方法是让旧版本的服务附带一个新版本的帮助程序,但是。。。如果它的行为必须以破坏性的方式改变呢?我觉得不混淆版本更安全,即使有些东西通常保持不变,这有助于降低设计复杂性

现在,在Windows服务上似乎有一种与.Net版本无关的操作方式:
sc.exe
工具:

我不知道这是否真的是我所寻找的银弹。现在,因为我将以编程方式调用这个家伙,并检查错误,所以我还可以为此使用API。理想情况下,我将有一个本地C++项目,它编译成与SC.exe接口的本地EXE。这可能吗?如果没有,那么如何在不同的计算机上查找sc.exe?它们可以是32位或64位,运行以Win XP SP2/3开始的任何Windows版本

如果您对我的问题有任何疑问,或者有什么独创性的想法,或者对我在这里提出的问题有什么回答,请告诉我


编辑:如果我尝试使用2.0代码安装4.0服务,我会收到与以下操作相同的错误:

> C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe MyService4.exe
Microsoft(R).NET框架 安装实用程序版本 2.0.50727.4927版权所有(c)微软公司。版权所有

初始化时发生异常 安装: System.BadImageFormatException:无法 不加载文件或程序集 'file:///[path]\MyService4.exe'或一个 它的依赖性。这个大会是 由比 当前已加载运行时,无法删除 加载


我不知道你这是什么意思:

问题是.NET2.0库无法在.NET4.0服务上运行

ServiceController
类能够控制任何服务,甚至是本地服务。我没有尝试过,但我相信
ServiceInstaller
类也可以用来(取消)安装任何服务


如果
ServiceController
ServiceInstaller
不能满足您的需要,我建议直接包装本机API,而不是
sc.exe
。这本书应该让你开始;您将需要服务控制管理器功能。
sc.exe
程序只是围绕SCM API的一个简单的命令行包装。

作为更新包的一部分,包括一个名称在版本之间不会更改的可执行文件,例如Setup.exe:-)

然后,当更新逻辑作为新进程启动时,该工具将执行所有设置工作。它应该使用与包的其余部分相同的框架版本进行编译,以避免CLR版本控制问题

我在现有的
ServiceInstaller
类中遇到的最大问题是缺少对更新服务功能的支持,例如描述和故障/恢复操作。为了解决这个问题,我调整并使用了
ServiceInstallerEx
类。他的代码包括调用与
SC.exe
相同的Windows API所需的代码


有些关联:如果您的更新要求与我以前使用过的类似,我建议您安装到并列文件夹(其名称包括版本/发行号),并保留最后2或3个文件夹以允许回滚。将当前版本的路径传递给安装工具,以便它知道当前播放状态。

sc.exe实际上始终位于同一路径:%windir%\System32\sc.exe(x64将System32用于64位二进制文件:-)。不知道您当前的安装程序是什么样子的,但是如果您有,或者可以切换到MSI-它可以运行自定义安装操作,可以是您的新.exe,配置文件可以是SCM API,也可以只是启动sc.exe 2-3次,以执行停止、配置、启动。从技术上讲,您甚至可以在MSI中使用.cmd作为自定义安装操作,但它可能看起来有点难看(用户看到cmd窗口即将出现)

<如果你想去SCM API,你知道你的C++,那肯定是最好的方法——没有中间层来搞糟。此外,一旦你有单独的二进制,只用于安装任务,你就不受.NET的嵌入式安装过程的约束。你可以从C++和C++中获得相同的NT API。strong>关键是执行管理任务的二进制文件要停止、启动、配置等。服务必须与服务本身的二进制文件不同-这是.NET的问题-汇总起来


由于您正在执行一个主要的切换,如果您以前的安装不在MSI下,那么新的MSI将无法自己处理所有事情,因此您可能需要删除一个.cmd文件,使用sc.exe停止并清理旧的服务,只需开始清理,然后启动新的安装二进制文件-无论它是什么。MSI将停止并取消安装窗口服务,但前提是MSI以前安装了该服务。这种方式有点粘:-< /p> < p>你的本地C++应用程序可以调用这里所记录的函数:(其他人提到的SCM API)

你会想按照

OpenSCManager
OpenService (or CreateService)
ChangeServiceConfig
CloseServiceHandle

“如果ServiceController和ServiceInstaller不能满足您的需要”-您是对的,他们不能。我使用的
ServiceInstaller
库相当于使用特定.net Framework附带的installutil.exe。