下面的是KeSummer给我的问题的答案,其所说的方法和提供的代码经过验证时可行的,感谢KeSummer的指点。
原帖地址链接:http://topic.csdn.net/u/20090108/16/d5aebfec-b916-449e-ae88-02dd45388804.html#replyachor
原理:zipfldr.dll是个COM组件,但是尚未公开接口,但是我们可以打开一个隐藏的explorer窗口,然后把ZIP的内容悄悄地复制出来,这就相当于解压了。下面是代码,测试例子:UnZipFolder("d://aa.zip","c://解压文件夹");请确保c盘下解压文件夹存在。。。
bool UnZipFolder(LPCTSTR zipFile,LPCTSTR destination)
{
DWORD strlen = 0;
HRESULT hResult;
IShellDispatch *pISD;
Folder *pToFolder = NULL;
Folder *pFromFolder = NULL;
FolderItems *pFolderItems = NULL;
FolderItem *pItem = NULL;
VARIANT vDir, vFile, vOpt;
BSTR strptr1, strptr2;
CoInitialize(NULL);
bool bReturn = false;
hResult = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER,
IID_IShellDispatch, (void **)&pISD);
if(FAILED(hResult))
{
return bReturn;
}
VariantInit(&vOpt);
vOpt.vt = VT_I4;
vOpt.lVal = 16+4; // Do not display a progress dialog box ~ This will not work properly!
CString strZipFile(zipFile);
CString strDestination(destination);
strptr1 = strZipFile.AllocSysString();
strptr2 = strDestination.AllocSysString();
VariantInit(&vFile);
vFile.vt = VT_BSTR;
vFile.bstrVal = strptr1;
hResult = pISD->NameSpace(vFile, &pFromFolder);
VariantInit(&vDir);
vDir.vt = VT_BSTR;
vDir.bstrVal = strptr2;
hResult = pISD->NameSpace(vDir, &pToFolder);
if(S_OK == hResult)
{
hResult = pFromFolder->Items(&pFolderItems);
if(SUCCEEDED(hResult))
{
long lCount = 0;
pFolderItems->get_Count(&lCount);
IDispatch* pDispatch = NULL;
pFolderItems->QueryInterface(IID_IDispatch,(void**)&pDispatch);
VARIANT vtDispatch;
VariantInit(&vtDispatch);
vtDispatch.vt = VT_DISPATCH;
vtDispatch.pdispVal = pDispatch;
//cout << "Extracting files .../n";
hResult = pToFolder->CopyHere(vtDispatch,vOpt);
if(hResult != S_OK) return false;
//Cross check and wait until all files are zipped!
FolderItems* pToFolderItems;
hResult = pToFolder->Items(&pToFolderItems);
if(S_OK == hResult)
{
long lCount2 = 0;
hResult = pToFolderItems->get_Count(&lCount2);
if(S_OK != hResult)
{
pFolderItems->Release();
pToFolderItems->Release();
SysFreeString(strptr1);
SysFreeString(strptr2);
pISD->Release();
CoUninitialize();
return false;
}
//Use this code in a loop if you want to cross-check the items unzipped.
/*if(lCount2 != lCount)
{
pFolderItems->Release();
pToFolderItems->Release();
SysFreeString(strptr1);
SysFreeString(strptr2);
pISD->Release();
CoUninitialize();
return false;
}*/
bReturn = true;
}
pFolderItems->Release();
pToFolderItems->Release();
}
pToFolder->Release();
pFromFolder->Release();
}
//cout << "Over!/n";
SysFreeString(strptr1);
SysFreeString(strptr2);
pISD->Release();
CoUninitialize();
return bReturn;
}