我必须编写一个自动更新服务,在我们的客户端PC上更新我们公司的应用程序。要更新的应用程序之一是更新程序本身。我使用WIX创建的MSI包部署所有应用程序。
然后该服务使用“msiexec.exe / q / i”进行扫描以启动静默安装。
这适用于其他产品,但是当我想更新正在运行的服务时,该服务就是启动调用安装程序的过程的服务。因此,我正在尝试更新正在运行的进程。
我该怎么做? “分叉”安装程序进程并退出服务?使用一些聪明的Windows内置方法?
答案 0 :(得分:2)
感谢您提供的意见,以下是我提出的建议:
我正在使用具有MajorUpgrade支持的WIX安装程序和ServiceInstall元素来安装新服务。这将导致MSI停止服务并升级安装。
现在,要从中更新服务,我需要异步启动安装程序,然后允许正在运行的服务停止。
基本上我们需要打电话:
msiexec /package path_to_msi /quiet
由于CreateProcess需要可执行文件的完整路径,我使用SHGetKnownFolderPath来检索系统上的SYSTEM32路径
// note: FOLDERID_SystemX86 will return 32 bit version of system32 regardless of application type
PWSTR str = nullptr;
if (SHGetKnownFolderPath(FOLDERID_SystemX86, KF_FLAG_DEFAULT, NULL, &str) != S_OK)
throw std::runtime_error("failed to retrieve FOLDERID_SystemX86");
std::string exe = ...path to msiexec...;
std::string options = " /package \"path_to_msi\" /quiet";
现在,我们开始这个过程:
// start process
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (!CreateProcess(exe.c_str(), // application name
options.c_str(), // Command line options
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi)) // Pointer to PROCESS_INFORMATION structure
throw std::runtime_error("CreateProcess failed");
我们已经完成了。
安装程序现在将发出停止服务信号,确保正确处理!
将安装新服务,并希望在几秒钟内恢复运行。
完成; - )
如果有人需要更多细节,请随便提出。