Windows の C++ で zip ファイルをフォルダに(再帰的に)展開するには以下のようなプログラムでできます。
一番大きな注意点は、解凍先のフォルダをあらかじめ作ってから UnzipToFolder() を呼ばなければ失敗します(falseが返ってきます)。
msvc でも mingw の g++ でもビルドできます。
COMを使っているので呼び出しにそれなりの作法があります。(この記事では詳しく解説しません)
main.cpp
#include <windows.h>
#include <shlobj.h>
#include <iostream>
#include <filesystem>
bool UnzipToFolder(BSTR lpZipFile, BSTR lpFolder);
int main()
{
std::cout << "(begin)" << std::endl;
CoInitialize(NULL);
BSTR bstrFile = SysAllocString(L"c:\\temp2\\openjdk20-20-36.zip");
BSTR bstrPath = SysAllocString(L"c:\\temp2\\sample");
std::filesystem::create_directories(L"c:\\temp2\\sample");
BOOL b = UnzipToFolder(bstrFile, bstrPath);
SysFreeString(bstrFile);
SysFreeString(bstrPath);
CoUninitialize();
std::cout << "(end)" << b << std::endl;
return 0;
}
bool UnzipToFolder(BSTR lpZipFile, BSTR lpFolder)
{
IShellDispatch *pISD;
Folder *pZippedFile = 0L;
Folder *pDestination = 0L;
long FilesCount = 0;
IDispatch* pItem = 0L;
FolderItems *pFilesInside = 0L;
VARIANT Options, OutFolder, InZipFile, Item;
if (CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **)&pISD) != S_OK)
return false;
InZipFile.vt = VT_BSTR;
InZipFile.bstrVal = lpZipFile;
pISD->NameSpace(InZipFile, &pZippedFile);
if (!pZippedFile)
{
pISD->Release();
return false;
}
OutFolder.vt = VT_BSTR;
OutFolder.bstrVal = 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 false;
}
pFilesInside->QueryInterface(IID_IDispatch, (void**)&pItem);
Item.vt = VT_DISPATCH;
Item.pdispVal = pItem;
Options.vt = VT_I4;
//Options.lVal = 1024 | 512 | 16 | 4; //https://learn.microsoft.com/ja-jp/windows/win32/shell/folder-copyhere
Options.lVal = 1024 | 512 | 16; //https://learn.microsoft.com/ja-jp/windows/win32/shell/folder-copyhere
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;
}