使用MakeCab工具创建CAB文件

在软件开发过程中,经常需要将多个文件打包成一个单一的.cab文件,并且对这些文件进行代码签名。虽然.cab格式看起来已经有些过时,但它仍然是微软在需要将文件打包到安装程序中时的首选格式。本文将介绍如何使用MakeCab工具以及C++编程语言来实现这一过程。

.cab文件格式是由微软创建的,用于将安装程序的一部分文件打包到磁盘中。尽管这种格式已经有些过时,但直到今天,创建.cab文件时仍然会生成名为"Disk1"、"Disk2"等的文件夹。本文将介绍一种简化的方法,通过一个简单的函数调用来实现文件打包。

构建基础

在Secured Globe, Inc.中,使用了一些基础构建块。首先是一个执行命令的函数,该函数可以模拟在CMD中输入并执行命令,收集结果并将其显示回来。如果发生错误,它会生成一个友好的错误描述。

bool DoRun(WCHAR *command) { DWORD retSize; LPTSTR pTemp = NULL; TCHAR Command[BUFSIZE] = L""; DeleteFile(RESULTS_FILE); _tcscpy_s(Command, L"/C "); _tcscat_s(Command, command); _tcscat_s(Command, L">"); _tcscat_s(Command, RESULTS_FILE); wprintf(L"Calling:\n%s\n", Command); bool result = ShellExecute(GetActiveWindow(), L"OPEN", L"cmd", Command, NULL, 0L); Sleep(1000); if (result) { std::FILE *fp = _wfopen(RESULTS_FILE, L"rb"); if (fp) { std::string contents; std::fseek(fp, 0, SEEK_END); contents.resize(std::ftell(fp)); std::rewind(fp); std::fread(&contents[0], 1, contents.size(), fp); std::fclose(fp); CString temp1 = (CString)(CStringA)(contents.c_str()); wprintf(L"Result:\n%s\n", temp1.GetBuffer()); } } else { retSize = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL, GetLastError(), LANG_NEUTRAL, (LPTSTR)&pTemp, 0, NULL); return (L"Error: %s\n", pTemp); } }

CreateCabFromFiles函数

在CreateCabFromFiles函数中,定义了一些常量,然后使用这些常量来创建.cab文件。这个函数接受一个目标.cab文件名和文件数量,然后创建一个包含所有文件名的列表文件,并调用MakeCab工具来打包这些文件。

#define RESULTS_FILE L"result.txt" #define FILELIST_FILE L"files.txt" #define MAKECAB_COMMAND L"makecab /d CabinetName1=%s /f %s" #define CAB_DEF_FOLDER L"disk1" bool CreateCabFromFiles(LPWSTR TargetCab, int argc, ...) { va_list ptr; va_start(ptr, argc); FILE *fp = _wfopen(FILELIST_FILE, L"w"); if (fp) { for (int i = 0; i < argc; i++) { LPWSTR *filetowrite = va_arg(ptr, LPWSTR *); fwprintf(fp, L"%s\n", filetowrite); } fclose(fp); CString command; command.Format(MAKECAB_COMMAND, TargetCab, FILELIST_FILE); if (DoRun(command.GetBuffer())) { if (CopyFile(CAB_DEF_FOLDER + (CString)L"\\" + TargetCab, TargetCab, FALSE)) { wprintf(L"Created cab file: %s\n", TargetCab); DeleteFile(CAB_DEF_FOLDER + (CString)L"\\" + TargetCab); RemoveDirectory(CAB_DEF_FOLDER); DeleteFile(FILELIST_FILE); return true; } } } return true; }

清理工作

为了节省打开"disks"并查找创建的.cab文件的需要,以及删除为了正确"喂养"MakeCab而创建的文件,这个函数的清理工作包括以下步骤:

  • 将.cab文件从"disk1"复制到当前路径。
  • 清空并删除"disk1"文件夹。
  • 删除用于托管要添加的文件列表的文件。
  • 删除用于DoRun()函数的"results"文件。
CreateCab(L"drivers.cab", 3, L"drv.sys", L"drv.inf", L"drv.cat");
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485