山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他ZIPファイルを解凍する
概要
シェルが提供するIShellDispatchを用いてZIPファイルを解凍します。
IShellDispatchには、ファイル名を指定して実行(FileRun)や検索などがあります。
Windows XPより標準でZIP圧縮機能が搭載されました。
本プログラムでは、C:¥temp2¥sample.zipファイルをC:¥temp2¥sampleフォルダーに解凍します。
C:¥temp2¥sampleフォルダーは予め作成しておく必要があります。
IShellDispatchには、ファイル名を指定して実行(FileRun)や検索などがあります。
Windows XPより標準でZIP圧縮機能が搭載されました。
本プログラムでは、C:¥temp2¥sample.zipファイルをC:¥temp2¥sampleフォルダーに解凍します。
C:¥temp2¥sampleフォルダーは予め作成しておく必要があります。
テスト環境
コンパイラ
Visual C++ 2013 Express 32/64bit Windows 7/10プログラムソースの概要
_tmain関数
Windowsから最初に_tmain関数が呼び出されます。COMインターフェースをCoInitializeExで初期化します。
CoCreateInstanceによりIShellDispatchオブジェクトを取得します。
ExtractZip関数を呼び出してZIPファイルを指定フォルダーへ解凍します。
CoUninitializeでCOMインターフェースを解放します。
ExtractZip
ZIPファイル中身(Items)のフォルダー型から解凍先のフォルダーのFolder型へコピーすることにより解凍することができます。圧縮と異なり実際に実行すると非同期動作はしていませんでしたので圧縮に比べると単純なプログラムとなります。 以下のような手順で処理します。- 解凍先フォルダー名(TCHAR*型)からVARIANT型を作成しNameSpaceによりFolder型オブジェクトを作成します。
VARIANT型は不要ですのでVariantClearにより解放します。 - ZIPファイル名(TCHAR*型)からVARIANT型を作成しNameSpaceによりFolder型オブジェクトを作成します。
VARIANT型は不要ですのでVariantClearにより解放します。 - ZIPファイルのFolder型の中身をitemsで取得します。
- 解凍先のFolder型のCopyHere関数により解凍します。
- 各オブジェクトを解放して関数を終了します。
プログラムソース
// ZIPファイルの展開(Unicode専用)
// あらかじめ展開先フォルダーを作成する必要が有ります。
// Visual C++ 2013
#include <windows.h>
#include <shlobj.h>
#include <tlhelp32.h>
#include <locale.h>
#include <tchar.h>
// ZIPファイルの展開
BOOL ExtractZip(IShellDispatch *pShellDisp, TCHAR* ZipPath, TCHAR* OutPath);
void _tmain(void){
HRESULT hr;
IShellDispatch *pShellDisp;
// UNICODE文字を標準出力に正しく表示させるためにロケールを設定
_tsetlocale(LC_ALL, _TEXT(""));
CoInitializeEx(0, COINIT_MULTITHREADED);
hr = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pShellDisp));
if (FAILED(hr)) {
CoUninitialize();
return;
}
// ZIPファイル 展開先
ExtractZip(pShellDisp, _TEXT("c:¥¥temp2¥¥sample.zip"), _TEXT("c:¥¥temp2¥¥sample"));
CoUninitialize();
return;
}
BOOL ExtractZip(IShellDispatch *pShellDisp, TCHAR* ZipPath, TCHAR* OutPath){
HRESULT hr;
VARIANT vDtcDir;
Folder *pOutDtc;
// 展開先Folderオブジェクトを作成
VariantInit(&vDtcDir);
vDtcDir.vt = VT_BSTR;
vDtcDir.bstrVal = SysAllocString(OutPath);
hr = pShellDisp->NameSpace(vDtcDir, &pOutDtc);
VariantClear(&vDtcDir);
if (hr != S_OK){
MessageBox(NULL, TEXT("展開先フォルダーが見つかりませんでした。"), NULL, MB_ICONWARNING);
return FALSE;
}
// ZIPファイルのFolderオブジェクトを作成
VARIANT varZip;
Folder *pZipFile;
VariantInit(&varZip);
varZip.vt = VT_BSTR;
varZip.bstrVal = SysAllocString(ZipPath);
hr = pShellDisp->NameSpace(varZip, &pZipFile);
VariantClear(&varZip);
if (hr != S_OK) {
pOutDtc->Release();
MessageBox(NULL, TEXT("ZIPファイルが見つかりませんでした。"), NULL, MB_ICONWARNING);
return FALSE;
}
// ZIPファイルの中身を取得
FolderItems *pZipItems;
hr = pZipFile->Items(&pZipItems);
if (hr != S_OK) {
pZipFile->Release();
pOutDtc->Release();
return FALSE;
}
VARIANT vDisp, vOpt;
VariantInit(&vDisp);
vDisp.vt = VT_DISPATCH;
vDisp.pdispVal = pZipItems;
VariantInit(&vOpt);
vOpt.vt = VT_I4;
vOpt.lVal = 0; //FOF_SILENTを指定すると処理中の経過が表示されなくなります
// ZIPファイルの中身を展開先フォルダーにコピー
hr = pOutDtc->CopyHere(vDisp, vOpt);
if (hr != S_OK) {
pZipItems->Release();
pZipFile->Release();
pOutDtc->Release();
MessageBox(NULL, TEXT("展開に失敗しました。"), NULL, MB_ICONWARNING);
return FALSE;
}
pZipItems->Release();
pZipFile->Release();
pOutDtc->Release();
return TRUE;
}
ソースファイルと実行ファイルのダウンロード
Copyright (C) 2012 山本ワールド All Rights Reserved.