zoukankan      html  css  js  c++  java
  • 如何创建 CAB 文件和如何从文件、内存和资源中解压缩 CAB 文件

    制作 MSI 安装程序少不了 CAB 文件,CAB 文件可以对需要安装程序进行压缩,以达到快速分发新程序的目的,通过参考高人的代码和 MSDN 整理了一套 Cabinet 文件的操作实现类,使用这些类可以:
      1、将多个文件制作为一个 CAB 文件
      2、将一个目录直接打包为 CAB 文件
      3、将磁盘上的 CAB 文件中解包出文件
      4、从内存中的 CAB 数据流中解包出文件 
      5、从程序的 CAB 资源中解包出文件
      6、通过策略模式可以对 CAB 文件中的数据进行加解密

    通过该套封装类,已经实现了制作单文件的安装程序 Setup.exe ,该程序使用 /Create 参数启动时根据指定的目录打包为一个 CAB 文件并将该文件加入到特定的资源中生成一个用于安装的 Setup.exe(同一个程序,如果没有指定参数那么根据有无 CAB 资源来决定是进行“安装”还是“卸载”),在程序中添加资源很简单,参考下面的例子代码:

        //--------------------------------------------------------------------------
        
    //    概述:
        
    //        根据指定的程序和 CAB 文件创建安装程序
        
    //    参数:
        
    //        szInstall    - [ IN ]    生产的目标安装程序路径
        
    //        szPackage    - [ IN ]    安装程序使用的 CAB 文件路径
        
    //        szProgram    - [ IN ]    原始的安装程序路径
        BOOL CreateSetup(LPTSTR szInstall, LPTSTR szPackage, LPTSTR szProgram);
      下面是该函数的实现:
    BOOL CPagePackage::CreateSetup(LPTSTR szInstall, LPTSTR szPackage, LPTSTR szProgram)
    {
        
    //    复制安装程序到目标路径处
        BOOL bCopy = CopyFile(szProgram, szInstall, FALSE);
        CHK_EXP_RET( FALSE 
    == bCopy , ShowSystemError() );

        
    //    打开 CAB 文件
        HANDLE hFile = CreateFile(szPackage, GENERIC_READ, 00, OPEN_ALWAYS, 00);
        CHK_EXP_RET( hFile 
    == INVALID_HANDLE_VALUE , ShowSystemError() );
        BasicHelper::CHandleManager xAutoFileManager( hFile );

        
    //    创建 CAB 文件到共享内存映射的句柄
        HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 00, NULL );
        CHK_EXP_RET( hMapping 
    == NULL , ShowSystemError() );
        BasicHelper::CHandleManager xMapping( hMapping );

        CONST LPCTSTR szResName 
    = MAKEINTRESOURCE( 1 );
        CONST WORD wLanguage 
    = MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED);

        
    //    获取 CAB 文件大小
        DWORD dwSize = GetFileSize( hFile, ERROR_SUCCESS + NO_ERROR );
        CHK_EXP_RET( dwSize 
    == INVALID_FILE_SIZE , ShowSystemError() );

        
    //    将 CAB 文件映射到共享内存中
        LPVOID lpBuffer = MapViewOfFile(hMapping, FILE_MAP_READ, 000);
        CHK_EXP_RET( lpBuffer 
    == NULL , ShowSystemError() );

        
    //    准备将 CAB 文件内容添加到安装程序中
        HANDLE hUpdate = BeginUpdateResource(szInstall, FALSE);
        CHK_EXP_RET( hUpdate 
    == NULL , ShowSystemError() );

        
    //    将 CAB 文件内容更新到目标安装程序的资源中
        UpdateResource(hUpdate, RT_RCDATA, szResName, wLanguage, lpBuffer, dwSize);
        EndUpdateResource(hUpdate, FALSE);
        UnmapViewOfFile(lpBuffer);
        
    return NO_ERROR + TRUE;
    }
      呵呵,最后附上 CAB 文件完整的实现文件:
    CabinetImpl.h
  • 相关阅读:
    PowerCat DNS 隧道通信
    各种反弹shell方法总结备忘
    Halo-个人独立博客系统
    内网渗透之域渗透
    使用 EW 作Socks5代理内网穿透
    PowerShell攻击:nishang
    贝叶斯网络
    Anaconda的CondaHTTPError问题
    完美解决win10系统无法安装.NET Framework问题
    敏捷开发中如何做质量管理?
  • 原文地址:https://www.cnblogs.com/WonKerr/p/CabinetImpl.html
Copyright © 2011-2022 走看看