安装包的静默安装和卸载
安装包的静默安装与卸载
关键词:
安装包,XPSmsiWindows UpdateInstallShield,静默安装
  要:
TL 5.0的安装包需要处理XPS虚拟打印机的安装,同时还要处理PCMT的卸载,这就需要我们处理第三方软件的安装和卸载。在处理过程中,我们采用静默的方式,本文总结了开发过程中涉及到的msi类型的安装包、Windows系统补丁和InstallShield类型的安装包的静默安装和卸载的方法。
1、 案例描述
TL5.0的安装包需要处理XPS虚拟打印机的安装,还有PCMT的卸载,为了提升用户体验,XPS虚拟打印机的安装和PCMT的卸载都采用静默的方式。XPS虚拟打印机的安装包是微软提供的msi类型的安装包,PCMT则是InstallShield类型的安装包,这两种类型的安装包都可以通过命令行参数进行静默安装和卸载。
XPS虚拟打印机安装包只需要在XP系统下安装,Win7及以上系统则作为系统组件提供,不需要人为去安装了。微软的XPS安装包分32位和64位版,都打包到TL5.0的安装包中,会占用17M的空间,这样整个安装包的大小会突破50M的限制。通过剥离XPS安装包发现:独立的XPS打印机的安装程序其实是一个Windows补丁包,而系统补丁是可以通过命令行参数进行静默安装的,并且剥离出来的2个XPS补丁还不到7M,有效的降低了TL5.0安装包的大小。
2、 MSI安装包的静默安装与卸载
紫金牛
当安装程序完成文件的拷贝后会启动XPS虚拟打印机的安装程序,进行静默安装。
2.1 MSI安装包的静默安装与卸载
msi文件是Windows Installer的数据包,它实际上是一个数据库,包含安装一种产品所需要的信息和在很多安装情形下安装(和卸载)程序所需的指令和数据,msi安装包的安装需要依赖Windows Installer服务:
在非禁用状态下,双击msi类型的安装包,系统会自动启动Windows Installer服务。禁用该服务将无法正常安装任何msi类型的安装包,系统提示如下:
Windows下可以用msiexec命令管理msi安装包,dos下输入msiexec /?会弹出msiexec命令行参数相关的帮助对话框:(或者在运行中直接输入msiexec,也会弹出如下的窗口)
为避免msi安装包安装完后重启,还可以指定相应的重新启动选项:
命令行下使用msiexec静默安装msi软件包命令行脚本示例:
// 静默安装XPS虚拟打印机,安装完后不重启
msiexec  /i "E:\XPS\XPSEP XP and Server 2003 32 bit.msi" /quiet /norestart
2.2 MSI安装包的剥离
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安装包达到17M左右,都要打包到TL5.0的安装包中,会使安装包变得很大,这应该是不合理的,是需要优化的。另外,这个XPS虚拟打印机是用户不感知的,如果在安装TL时在桌面上生成一个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虚拟打印机的安装程序:
3、 系统补丁的静默安装与卸载
从XPSEP XP and Server 2003 32 bit.msi和XPSEP XP and Server 2003 64 bit.msi中分别提取出对应的SCUPDATE文件,将文件类型改为exe类型,双击启动该文件发现SCUPDATE其实就是Windows的一个系统补丁:
安装完成后,可以查看到已安装的系统补丁:
    Windows的系统补丁支持命令行参数,通过设置相应的参数也能实现静默安装,在MSDN中可以搜索到相关主题的详细说明:
    命令行下静默安装Windows补丁命令行脚本示例:
// 补丁包名称+命令行参数
E:\XPS\ /u /q /z
    使用CreateProcess静默安装XPS虚拟打印机的补丁包代码如下:
// lpszCmdLineParam:补丁包的绝对路径
BOOL CProcessLogic::CreateXpsInstallProcess( LPCTSTR lpszCmdLineParam )
{
    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, lpszCmdLineParam );
    _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;
}
4、 InstallShield安装包静默安装与卸载
TL5.0的安装包还需要对老版本的PCMT进行处理,如果用户选择替换原PCMT版本,安装程序会在安装过程中需要静默卸载PCMT。PCMT是InstallShield类型的安装包,它的静默安装与msi类型的安装包不同,InstallShield的静默安装需要有录制好的response file(.iss文件,iss-InstallShield Silent)。
InstallShield静默安装与卸载对应的命令行参数如下:(InstallShield上有相关的说明)
使用/r的参数可以录制安装或卸载的response file(iss文件)。iss文件一般需要我们手动去录制,可以在命令行窗口中,切换到卸载程序所在的目录,然后执行类似 /r /f1”E:\PCMT\uninst.iss”命令,在弹出的卸载向导中依次点击完成卸载,这样就自动生成iss文件,记录下执行卸载向导过程中的操作。命令行录制PCMT卸载的iss文件命令行脚本示例:
// 切换到PCMT卸载程序所在目录
cd “C:\Program Files\InstallShield Installation Information\{6C92A6FD-CF96-4A49-A7DD-AFE46D2EFECB}”
// 录制静默卸载PCMT的iss文件,/r录制模式,/f1指定生成iss文件路径(/f1与路径之间没有空格)
/r /f1”E:\PCMT\uninst.iss”
将手动录制好的iss打开,iss文件的内容如下,该文件记录了执行卸载向导过程中的操作:
[InstallShield Silent]
Version=v7.00
File=Response File
[File Transfer]
OverwrittenReadOnly=NoToAll
[{6C92A6FD-CF96-4A49-A7DD-AFE46D2EFECB}-DlgOrder]
Dlg0={6C92A6FD-CF96-4A49-A7DD-AFE46D2EFECB}-SdWelcomeMaint-0
Count=3
Dlg1={6C92A6FD-CF96-4A49-A7DD-AFE46D2EFECB}-MessageBox-0
Dlg2={6C92A6FD-CF96-4A49-A7DD-AFE46D2EFECB}-SdFinishReboot-0
[{6C92A6FD-CF96-4A49-A7DD-AFE46D2EFECB}-SdWelcomeMaint-0]
Result=303
[{6C92A6FD-CF96-4A49-A7DD-AFE46D2EFECB}-MessageBox-0]
Result=6
[Application]
Name=Meeting Terminal
Version=1.00.0000
Company=Kedacom
Lang=0804
[{6C92A6FD-CF96-4A49-A7DD-AFE46D2EFECB}-SdFinishReboot-0]
Result=1
BootOption=0
使用 InstallShield的静默安装或卸载功能必须将相应的response file打包到InstallShield的安装包,因为PCMT的安装包并没有打包相应的response file,所以我们需要将PCMT静默卸载的响应文件打包到TL5.0的安装包,卸载PCMT时通过/s和/f1命令指定静默卸载和静默卸载所需的响应文件。
静默卸载PCMT的命令行脚本示例:
// 切换到PCMT卸载程序所在目录
cd “C:\Program Files\InstallShield Installation Information\{6C92A6FD-CF96-4A49-A7DD-AFE46D2EFECB}”
// 静默卸载PCMT,/s指定静默模式,/f1指定iss文件路径
/s /f1”E:\PCMT\uninst.iss”
静默卸载PCMT代码如下:
// 静默方式卸载PCMT
void CProcessLogic::UninstallPcmt()
{
    // PCMT卸载信息中取出卸载程序的绝对路径
    int nIndex = m_strPcmtUninstInfo.Find( _T("") );
    if ( nIndex < 0 )
    {
        return;
    }
    CString strCmdLineParam = m_strPcmtUninstInfo.Left( nIndex );
    strCmdLineParam.Append( _T("") );
    // PCMT卸载使用的iss文件的绝对路径
    CString strIssFilePath = _T('"') + m_strCopySrcPath + _T("targetdir\\uninst.iss\"");
    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, strCmdLineParam );
    // InstallShield静默卸载的命令行参数
    _tcscat( achCmdLine, _T(" /s /f1") );
    _tcscat( achCmdLine, strIssFilePath );
    if( !CreateProcess( NULL, achCmdLine, NULL, 调料蛋NULL, FALSE, 0, NULL, NULL, &si, &pi ) )
    {
        DWORD dwError = GetLastError();
        CString strLog;
        strLog.Format( _T("[CProcessLogic::UninstallPcmt]uninstall PCMT failed GetLastError: %d"), dwError );
        uilog( strLog );
        return ;
    }
    // 最长等待3分钟
    WaitForSingleObject( pi.hProcess, 180000 );
    // 将进程句柄和线程句柄关闭掉,否则会有句柄泄漏
    CloseHandle( pi.hThread );
    CloseHandle( pi.hProcess );
    return ;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。