如评论中所述,这仅适用于已创建的Zip文件。内容也不能已经存在于Zip文件中,否则将显示错误。以下是我根据已接受答案创建的工作示例代码。您需要链接shell32.lib和kernel32.lib(用于CreateToolhelp32Snapshot)。
#include <windows.h>
#include <shldisp.h>
#include <tlhelp32.h>
#include <stdio.h>
int main(int argc, TCHAR* argv[])
{
DWORD strlen = 0;
char szFrom[] = "C:\\Temp",
szTo[] = "C:\\Sample.zip";
HRESULT hResult;
IShellDispatch *pISD;
Folder *pToFolder = NULL;
VARIANT vDir, vFile, vOpt;
BSTR strptr1, strptr2;
CoInitialize(NULL);
hResult = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **)&pISD);
if (SUCCEEDED(hResult) && pISD != NULL)
{
strlen = MultiByteToWideChar(CP_ACP, 0, szTo, -1, 0, 0);
strptr1 = SysAllocStringLen(0, strlen);
MultiByteToWideChar(CP_ACP, 0, szTo, -1, strptr1, strlen);
VariantInit(&vDir);
vDir.vt = VT_BSTR;
vDir.bstrVal = strptr1;
hResult = pISD->NameSpace(vDir, &pToFolder);
if (SUCCEEDED(hResult))
{
strlen = MultiByteToWideChar(CP_ACP, 0, szFrom, -1, 0, 0);
strptr2 = SysAllocStringLen(0, strlen);
MultiByteToWideChar(CP_ACP, 0, szFrom, -1, strptr2, strlen);
VariantInit(&vFile);
vFile.vt = VT_BSTR;
vFile.bstrVal = strptr2;
VariantInit(&vOpt);
vOpt.vt = VT_I4;
vOpt.lVal = 4;
hResult = NULL;
printf("Copying %s to %s ...\n", szFrom, szTo);
hResult = pToFolder->CopyHere(vFile, vOpt);
if (hResult == S_OK) {
HANDLE hThrd[5];
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPALL ,0);
DWORD NUM_THREADS = 0;
if (h != INVALID_HANDLE_VALUE) {
THREADENTRY32 te;
te.dwSize = sizeof(te);
if (Thread32First(h, &te)) {
do {
if (te.dwSize >= (FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID)) ) {
if((te.th32OwnerProcessID == GetCurrentProcessId()) && (te.th32ThreadID != GetCurrentThreadId()) ){
hThrd[NUM_THREADS] = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);
NUM_THREADS++;
}
}
te.dwSize = sizeof(te);
} while (Thread32Next(h, &te));
}
CloseHandle(h);
printf("waiting for all threads to exit...\n");
WaitForMultipleObjects(NUM_THREADS, hThrd , TRUE , INFINITE);
for ( DWORD i = 0; i < NUM_THREADS ; i++ ){
CloseHandle( hThrd[i] );
}
}
}
SysFreeString(strptr2);
pToFolder->Release();
}
SysFreeString(strptr1);
pISD->Release();
}
CoUninitialize();
printf ("Press ENTER to exit\n");
getchar();
return 0;
}
尽管我已经得到了半功能代码,但在进一步调查后,我决定不走这条路,因为似乎Folder::CopyHere()方法并没有实际遵循传递给它的vOptions参数,这意味着您不能强制覆盖文件或不向用户显示错误对话框。
鉴于此,我也试用了另一位发帖者提到的XZip库。该库用于创建Zip存档的功能良好,但请注意,使用ZIP_FOLDER调用的ZipAdd()函数不是递归的 - 它只在存档中创建一个文件夹。为了递归压缩存档,您需要使用AddFolderContent()函数。例如,要创建C:\Sample.zip并将C:\Temp文件夹添加到其中,请使用以下内容:
HZIP newZip = CreateZip("C:\\Sample.zip", NULL, ZIP_FILENAME);
BOOL retval = AddFolderContent(newZip, "C:", "temp");
重要提示:AddFolderContent()函数在XZip库中的功能不可用。它将递归进入目录结构,但由于传递给ZipAdd()的路径中存在错误,无法将任何文件添加到zip存档中。为了使用此函数,您需要编辑源代码并更改此行:
if (ZipAdd(hZip, RelativePathNewFileFound, RelativePathNewFileFound, 0, ZIP_FILENAME) != ZR_OK)
以下是相关内容:
ZRESULT ret;
TCHAR real_path[MAX_PATH] = {0};
_tcscat(real_path, AbsolutePath);
_tcscat(real_path, RelativePathNewFileFound);
if (ZipAdd(hZip, RelativePathNewFileFound, real_path, 0, ZIP_FILENAME) != ZR_OK)