bool CPathUtils::Unzip2Folder(LPCWSTR lpZipFile, LPCWSTR lpFolder) { IShellDispatch *pISD; Folder *pZippedFile = 0L; Folder *pDestination = 0L; long FilesCount = 0; IDispatch* pItem = 0L; FolderItems *pFilesInside = 0L; VARIANT Options, OutFolder, InZipFile, Item; HRESULT hr = S_OK; CoInitialize(nullptr); __try { if (CoCreateInstance(CLSID_Shell, nullptr, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **)&pISD) != S_OK) return false; InZipFile.vt = VT_BSTR; InZipFile.bstrVal = const_cast<BSTR>(lpZipFile); hr = pISD->NameSpace(InZipFile, &pZippedFile); if (FAILED(hr) || !pZippedFile) { pISD->Release(); return false; } OutFolder.vt = VT_BSTR; OutFolder.bstrVal = const_cast<BSTR>(lpFolder); pISD->NameSpace(OutFolder, &pDestination); if (!pDestination) { pZippedFile->Release(); pISD->Release(); return false; } pZippedFile->Items(&pFilesInside); if (!pFilesInside) { pDestination->Release(); pZippedFile->Release(); pISD->Release(); return false; } pFilesInside->get_Count(&FilesCount); if (FilesCount < 1) { pFilesInside->Release(); pDestination->Release(); pZippedFile->Release(); pISD->Release(); return true; } pFilesInside->QueryInterface(IID_IDispatch, (void**)&pItem); Item.vt = VT_DISPATCH; Item.pdispVal = pItem; Options.vt = VT_I4; Options.lVal = 1024 | 512 | 16 | 4;//http://msdn.microsoft.com/en-us/library/bb787866(VS.85).aspx bool retval = pDestination->CopyHere(Item, Options) == S_OK; pItem->Release(); pItem = 0L; pFilesInside->Release(); pFilesInside = 0L; pDestination->Release(); pDestination = 0L; pZippedFile->Release(); pZippedFile = 0L; pISD->Release(); pISD = 0L; return retval; } __finally { CoUninitialize(); } }
static int MyInvokeShellVerb_ShellDispatchProc(const TCHAR *pcDirectoryName, const TCHAR *pcFileName, const DWORD uiVerbId) { int iSuccess = 0; bool bUnloadDll = false; HMODULE hShellDll = GetModuleHandleW(shell32); if(hShellDll == NULL) { bUnloadDll = true; hShellDll = LoadLibraryW(shell32); if(hShellDll == NULL) { iSuccess = -3; return iSuccess; } } WCHAR pcVerbName[128]; memset(pcVerbName, 0, sizeof(WCHAR) * 128); if(LoadStringW(hShellDll, uiVerbId, pcVerbName, 128) < 1) { if(bUnloadDll) { FreeLibrary(hShellDll); hShellDll = NULL; } iSuccess = -3; return iSuccess; } if(bUnloadDll) { FreeLibrary(hShellDll); hShellDll = NULL; } // ----------------------------------- // IShellDispatch *pShellDispatch = NULL; Folder *pFolder = NULL; FolderItem *pItem = NULL; HRESULT hr = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void**)&pShellDispatch); if(FAILED(hr) || (pShellDispatch == NULL)) { iSuccess = -3; return iSuccess; } variant_t vaDirectory(pcDirectoryName); hr = pShellDispatch->NameSpace(vaDirectory, &pFolder); if(FAILED(hr) || (pFolder == NULL)) { iSuccess = -3; pShellDispatch->Release(); return iSuccess; } pShellDispatch->Release(); pShellDispatch = NULL; variant_t vaFileName(pcFileName); hr = pFolder->ParseName(vaFileName, &pItem); if(FAILED(hr) || (pItem == NULL)) { iSuccess = -3; pFolder->Release(); return iSuccess; } pFolder->Release(); pFolder = NULL; // ----------------------------------- // long iVerbCount = 0; FolderItemVerbs *pVerbs = NULL; hr = pItem->Verbs(&pVerbs); if(FAILED(hr) || (pVerbs == NULL)) { iSuccess = -3; pItem->Release(); return iSuccess; } pItem->Release(); pItem = NULL; hr = pVerbs->get_Count(&iVerbCount); if(FAILED(hr) || (iVerbCount < 1)) { iSuccess = -3; pVerbs->Release(); return iSuccess; } DispatchPendingMessages(125); // ----------------------------------- // for(int i = 0; i < iVerbCount; i++) { variant_t vaVariantIndex(i); FolderItemVerb *pCurrentVerb = NULL; BSTR pcCurrentVerbName = NULL; hr = pVerbs->Item(vaVariantIndex, &pCurrentVerb); if (FAILED(hr) || (pCurrentVerb == NULL)) { continue; } hr = pCurrentVerb->get_Name(&pcCurrentVerbName); if(FAILED(hr) || (pcCurrentVerbName == NULL)) { pCurrentVerb->Release(); continue; } if(_wcsicmp(pcCurrentVerbName, pcVerbName) == 0) { hr = pCurrentVerb->DoIt(); if(!FAILED(hr)) { iSuccess = 1; } } SysFreeString(pcCurrentVerbName); pCurrentVerb->Release(); } pVerbs->Release(); pVerbs = NULL; // ----------------------------------- // return iSuccess; }