目录
1、静默安装Microsoft Visual C++ 发行程序包VC_redist.x86.exe / VC_redist.x64.exe
1.1、参考WireShark静默安装VC_redist.x64.exe的操作,找到静默安装的实现方式
1.2、到微软官网上下载新版本或与Visual Studio对应版本的VC_redist.x86.exe / VC_redist.x64.exe
2、MSI安装包的静默安装与卸载
2.1、使用msiexec.exe静默安装MSI安装包
2.2、XPS虚拟打印机MSI安装包的剥离
3、系统补丁包的静默安装
4、最后
VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具案例集锦(专栏文章正在更新中...)https://blog.csdn.net/chenlycly/article/details/131405795C/C++基础与进阶(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_11931267.html 有时我们需要在程序安装包中嵌入其他程序的安装包,即在执行程序安装包的安装过程中需要启动其他程序的安装包进行安装,但又不希望看到其他程序安装包的UI界面,这时候就需要对其他程序的安装包启用静默安装模式。本文今天结合项目实践,来讲讲如何实现常见程序类型的静默安装。
Visual Studio编译出来的程序一般都需要C/C++运行时库,不同版本的Visual Studio对应的运行时库版本也有所不同,程序在启动时需要加载这些运行时库,如果在机器上找不到依赖的运行时库,则会报错,程序会启动失败。
对于程序需要的这些运行时库,可以直接将这些运行时库打包到程序安装包中,安装时直接拷贝到程序的安装路径中。也可以下载微软官方提供的Microsoft Visual C++ 发行程序包VC_redist.x86.exe / VC_redist.x64.exe:
将这个程序包集成到程序安装包中,执行程序安装操作时,先安装VC_redist.x86.exe / VC_redist.x64.exe。很多程序采用了后面的这种方式,比如我们常用的Windows版本的抓包工具WireShark,在安装过程中就能看到安装了VC_redist.x64.exe:
在执行VC_redist.x64.exe安装时,给VC_redist.x64.exe传入了三个参数:/install /quiet /norestart,其中/quiet参数表示静默安装,不弹出VC_redist.x64.exe的安装界面。
以VC_redist.x64.exe为例,其安装界面如下所示:
可以在cmd命令行窗口中切换到VC_redist.x64.exe程序的路径中,然后输入:VC_redist.x64.exe -help或者 VC_redist.x64.exe /help 查看VC_redist.x64.exe支持哪些具体的命令行参数,如下所示:
从上图中看了WireShark安装包中使用的三个参数:/install /quiet /norestart。
一般支持命令行传参的程序,都支持使用/help或者-help查看程序支持哪些命令行参数。对于Windows系统程序,还支持/?去查看。
通过C++代码去实现VC_redist.x64.exe的静默安装:
// lpszVCRedistExePath: VC_redist.x64.exe的绝对路径
BOOL QuietInstallHotfixPackage( LPCTSTR lpszVCRedistExePath)
{
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof(pi));
STARTUPINFO si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(STARTUPINFO);
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW;
TCHAR achCmdLine[MAX_PATH * 2] = { 0 };
_tcscpy(achCmdLine, lpszVCRedistExePath);
_tcscat(achCmdLine, _T(" /install /quiet /norestart")); // VC_redist.x64.exe静默安装命令行参数
if (!CreateProcess(NULL, achCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
return FALSE;
}
// 等待安装进程安装完成,安装完后再执行后续安装操作
// 参数INFINITE表示无限等待,直接安装进程自动退出
// 为了防止安装进程出问题,可以设置一个有限的等待时间
WaitForSingleObject(pi.hProcess, INFINITE);
// 可以调用API接口GetExitCodeProcess,获取进程退出码
// If the specified process has not terminated, the termination status returned is STILL_ACTIVE.
// If the process has terminated, the termination status returned may be one of the following:
// 1) The exit value specified in the ExitProcess or TerminateProcess function.
// 2) The return value from the main or WinMain function of the process.
// 3) The exception value for an unhandled exception that caused the process to terminate.
DWORD dwExitCode = 0;
GetExitCodeProcess(pi.hProcess, &dwExitCode);
// 将进程句柄和线程句柄关闭掉,否则会有句柄泄漏
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return TRUE;
}
在需要使用到VC_redist.x86.exe / VC_redist.x64.exe时,如果随意从网上下载,可能会和编译程序的Visual Studio版本不一致,还是会有问题。所以,建议大家到微软官方页面去下载最新版本或者对应版本的VC_redist.x86.exe / VC_redist.x64.exe:
Microsoft Visual C++ Redistributable latest supported downloadshttps://learn.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist
MSI的全称为Microsoft Installer,MSI文件是微软开发的一种基于Windows Installer的安装包文件,用于进行Windows系统软件的安装和升级。MSI文件是Windows Installer的数据包,它实际上是一个数据库,包含安装一种产品所需要的信息和在很多安装情形下安装(和卸载)程序所需的指令和数据,MSI安装包的安装需要依赖Windows Installer服务:
该服务在非禁用状态下,双击MSI类型的安装包,系统会自动启动Windows Installer服务完成MSI安装包的安装。如果禁用了该服务,则无法正常安装任何MSI类型的安装包,系统会提示如下信息:
Windows下可以用msiexec.exe系统程序去管理自行MSI安装包,在cmd命令行窗口中输入msiexec /?会弹出msiexec.exe的帮助对话框,可以从对话框中查看到msiexec.exe支持的命令行参数:
从上面我们看到了/quiet静默安装参数。将滚动条向下滚动,还可以看到/nostart安装完成后不重新启动选项:
所以,cmd命令行下使用msiexec静默安装MSI软件包的命令如下:
// 静默安MSI安装包,安装完后不重启
msiexec /i "E:\XXXXXX.msi" /quiet /norestart
项目中需要使用微软XPS虚拟打印机将pdf文档转换成图片,Win7及以上系统已经自带这个虚拟打印机了,但XP系统下是需要手动安装的(XP系统比较古老,但还有少部分客户还在使用XP系统,比如在某些ZF机构中)。
XP系统下安装XPS虚拟打印机需要的安装包分为XPSEP XP and Server 2003 32 bit.msi和XPSEP XP and Server 2003 64 bit.msi。在XP系统下安装完成后发现,除了安装了XPS虚拟打印机,还安装了XPS Viewer查看器,并在桌面生成了XPS Viewer的快捷方式,XPS Viewer和文档转换无关,是我们不需要的。而且这两个MSI安装包达到了17MB左右,都要打包到程序的安装包中,会明显增加安装包的大小,这点是需要优化的。另外,这个XPS虚拟打印机是用户不感知的,如果在桌面上生成一个XPS Viewer的快捷方式,用户会感觉很奇怪,所以这个桌面快捷方式也需要处理掉。
后来我们通过使用一些msi查看与编辑工具,比如Orca,Advanced Installer,MSI Studio,查看XPSEP XP and Server 2003 32 bit.msi发现安装包中Binary数据表中部分文件是exe文件:
后来用7-Zip或好压对XPSEP XP and Server 2003 32 bit.msi进行解压,将Binary表中对应的文件强制改为exe文件(再用7z对二进制文件解压,可以得到完整的xps安装文件),发现Binary表中的EPDPDATE和SCUPDATE分别是XPS Viewer和XPS虚拟打印机的安装程序:
从XPSEP XP and Server 2003 32 bit.msi和XPSEP XP and Server 2003 64 bit.msi中分别提取出对应的SCUPDATE文件,将文件类型改为exe类型,双击启动该文件发现SCUPDATE其实就是Windows的一个系统补丁:
安装完成后,可以查看到已安装的系统补丁:
Windows的系统补丁支持命令行参数,通过设置相应的参数也能实现静默安装。比如360安全卫士、腾讯管家在安装系统补丁时时看不到补丁安装界面的,应该使用的都是静默安装。在MSDN中可以搜索到相关主题的详细说明:
上述参数和msiexec.exe支持的命令行参数是类似的。在cmd命令行下静默安装Windows补丁命令为:
// 补丁包名称+命令行参数
E:\XPS\SCUPDATE_32bit.exe /u /q /z
使用C++代码实现补丁包程序的静默安装如下:
// lpszHotfixExePath:补丁包exe的绝对路径
BOOL QuietInstallHotfixPackage( LPCTSTR lpszHotfixExePath )
{
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof(pi));
STARTUPINFO si;
memset(&si, 0, sizeof(si));
si.cb = sizeof(STARTUPINFO);
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW;
TCHAR achCmdLine[MAX_PATH * 2] = { 0 };
_tcscpy(achCmdLine, lpszHotfixExePath);
_tcscat(achCmdLine, _T(" /u /q /z")); // Windows补丁静默安装命令行参数
if (!CreateProcess(NULL, achCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
return FALSE;
}
// 将进程句柄和线程句柄关闭掉,否则会有句柄泄漏
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return TRUE;
}
上面讲到了几种类型程序的静默安装的实现方式,希望能给大家提供一定的借鉴和参考。