Created
October 7, 2017 05:13
-
-
Save lxfly2000/24c7c3984128578e080e17eb0365d627 to your computer and use it in GitHub Desktop.
使用Windows自带的API解压zip文件。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<Windows.h> | |
#include<ShObjIdl.h> | |
#include<ShlObj.h> | |
#include<fstream> | |
LPWSTR TrimQuote(LPWSTR str) | |
{ | |
int ifrom = 0, ito = 0; | |
while (str[ifrom]) | |
{ | |
if (str[ifrom] != '\"') | |
{ | |
str[ito] = str[ifrom]; | |
ito++; | |
} | |
ifrom++; | |
} | |
return str; | |
} | |
//http://blog.csdn.net/xhhjin/article/details/6550467 | |
//释放使用 CoTaskMemFree | |
LPITEMIDLIST GetItemIDListFromFilePath(LPCTSTR strFilePath) | |
{ | |
if (!strFilePath) | |
{ | |
return NULL; | |
} | |
// 得到桌面的目录 | |
LPSHELLFOLDER pDesktopFolder = NULL; | |
HRESULT hr = SHGetDesktopFolder(&pDesktopFolder); | |
if (FAILED(hr)) | |
{ | |
return NULL; | |
} | |
// 得到文件路径对应的ItemIDList | |
LPITEMIDLIST pItemIDList = NULL; | |
TCHAR strbuf[MAX_PATH]; | |
lstrcpy(strbuf, strFilePath); | |
hr = pDesktopFolder->ParseDisplayName(NULL, NULL, strbuf, NULL, &pItemIDList, NULL); | |
pDesktopFolder->Release(); | |
if (FAILED(hr)) | |
{ | |
return NULL; | |
} | |
return pItemIDList; | |
} | |
BOOL ChooseDirectory(HWND hWndParent, TCHAR *fullPath, PCTSTR pcszDefaultPath, PCTSTR pcszTitle) | |
{ | |
IFileDialog *pf; | |
CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pf)); | |
FILEOPENDIALOGOPTIONS odo; | |
pf->GetOptions(&odo); | |
pf->SetOptions(FOS_PICKFOLDERS | odo); | |
pf->SetTitle(pcszTitle); | |
IShellItem *psi; | |
if (pcszDefaultPath) | |
{ | |
LPITEMIDLIST pi = GetItemIDListFromFilePath(pcszDefaultPath); | |
SHCreateShellItem(NULL, NULL, pi, &psi); | |
CoTaskMemFree(pi); | |
pf->SetFolder(psi); | |
psi->Release(); | |
} | |
if (pf->Show(hWndParent) == HRESULT_FROM_WIN32(ERROR_CANCELLED)) | |
{ | |
pf->Release(); | |
return FALSE; | |
} | |
TCHAR *compath; | |
pf->GetResult(&psi); | |
psi->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &compath); | |
lstrcpy(fullPath, compath); | |
CoTaskMemFree(compath); | |
psi->Release(); | |
pf->Release(); | |
return TRUE; | |
} | |
BOOL ChooseFile(HWND hWndParent, TCHAR *filepath, TCHAR *filename, PCTSTR pcszFiletype, PCTSTR pcszTitle) | |
{ | |
OPENFILENAME ofn = { 0 }; | |
ofn.lStructSize = sizeof OPENFILENAME; | |
ofn.hwndOwner = hWndParent; | |
ofn.hInstance = nullptr; | |
ofn.lpstrFilter = pcszFiletype; | |
ofn.lpstrFile = filepath; | |
ofn.lpstrTitle = pcszTitle; | |
ofn.nMaxFile = MAX_PATH; | |
ofn.lpstrFileTitle = filename; | |
ofn.nMaxFileTitle = MAX_PATH; | |
ofn.Flags = OFN_HIDEREADONLY; | |
return GetOpenFileName(&ofn); | |
} | |
//https://vcpptips.wordpress.com/tag/copyhere/ | |
int NewZipFile(const wchar_t *strFilePath) | |
{ | |
std::fstream fnzip; | |
fnzip.open(strFilePath, std::ios::in | std::ios::binary); | |
if (fnzip) | |
{ | |
fnzip.close(); | |
return -1; | |
} | |
char startBuffer[22] = { 80,75,5,6 }; | |
fnzip.open(strFilePath, std::ios::out | std::ios::binary); | |
if (!fnzip)return -2; | |
fnzip.write(startBuffer, std::size(startBuffer)); | |
fnzip.close(); | |
return 0; | |
} | |
__declspec(deprecated("该函数目前无法使用。"))int ZipFile(LPWSTR strSrc, LPWSTR strZipFile) | |
{ | |
if (NewZipFile(strZipFile))return -1; | |
IShellDispatch *ps; | |
Folder *ptof; | |
VARIANT vDir, vFile, vOpt; | |
CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **)&ps); | |
VariantInit(&vDir); | |
vDir.vt = VT_BSTR; | |
vDir.bstrVal = strZipFile; | |
ps->NameSpace(vDir, &ptof); | |
VariantInit(&vFile); | |
vFile.vt = VT_BSTR; | |
vFile.bstrVal = strSrc; | |
VariantInit(&vOpt); | |
vOpt.vt = VT_I4; | |
vOpt.lVal = NULL;// FOF_NO_UI; | |
if (FAILED(ptof->CopyHere(vFile, vOpt)))return -2; | |
ptof->Release(); | |
ps->Release(); | |
return 0; | |
} | |
//COM 函数 | |
int UnzipFile(LPWSTR strSrc, LPWSTR strFolder) | |
{ | |
IShellDispatch *ps; | |
Folder *pfromf, *ptof; | |
VARIANT vToDir, vFileFrom, vOpt;//OLE 类型 | |
CoCreateInstance(CLSID_Shell, nullptr, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void**)&ps); | |
VariantInit(&vToDir); | |
vToDir.vt = VT_BSTR; | |
vToDir.bstrVal = strFolder; | |
ps->NameSpace(vToDir, &ptof); | |
VariantInit(&vFileFrom); | |
vFileFrom.vt = VT_BSTR; | |
vFileFrom.bstrVal = strSrc; | |
ps->NameSpace(vFileFrom, &pfromf); | |
FolderItems *pfis; | |
pfromf->Items(&pfis); | |
VariantInit(&vOpt); | |
vOpt.vt = VT_I4; | |
vOpt.lVal = NULL;// FOF_NO_UI; | |
VARIANT vNew; | |
VariantInit(&vNew); | |
vNew.vt = VT_DISPATCH; | |
vNew.pdispVal = pfis; | |
if (FAILED(ptof->CopyHere(vNew, vOpt))) | |
return -1; | |
pfromf->Release(); | |
ptof->Release(); | |
ps->Release(); | |
return 0; | |
} | |
int wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) | |
{ | |
WCHAR zipfile[MAX_PATH] = L"", topath[MAX_PATH] = L".\\"; | |
bool cancelled = false; | |
if (FAILED(CoInitialize(NULL)))return -1; | |
if (__argc == 3) | |
{ | |
lstrcpy(zipfile, __wargv[1]); | |
TrimQuote(zipfile); | |
lstrcpy(topath, __wargv[2]); | |
TrimQuote(topath); | |
} | |
else | |
{ | |
if (!ChooseFile(NULL, zipfile, NULL, L"压缩文件(ZIP)\0*.zip\0所有文件\0*\0\0", NULL) || | |
!ChooseDirectory(NULL, topath, NULL, NULL)) | |
cancelled = true; | |
} | |
//解压文件 | |
if (!cancelled&&UnzipFile(zipfile, topath))return -2; | |
CoUninitialize(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment