// CZipFile3.cpp : このファイルには 'main' 関数が含まれています。プログラム実行の開始と終了がそこで行われます。 // #include #include #include #include #include #include #include #pragma comment(lib, "shlwapi") BOOL AddFileZip(IShellDispatch* pShellDisp, TCHAR* ZipPath, TCHAR* AddFilePath); int _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 0; } // ZIPファイル 追加するファイル AddFileZip(pShellDisp, (TCHAR*)(L"C:\\temp\\sample2.zip"), (TCHAR*)(L"C:\\temp\\test1.txt")); CoUninitialize(); return 0; } BOOL AddFileZip(IShellDispatch* pShellDisp, TCHAR* ZipPath, TCHAR* AddFilePath) { HRESULT hr; VARIANT vSrcFile; // 追加するファイル名のVARIANT型を作成 VariantInit(&vSrcFile); vSrcFile.vt = VT_BSTR; vSrcFile.bstrVal = SysAllocString(AddFilePath); // ZIPファイルが存在しない場合にZIPファイルの種を作成する if (PathFileExists(ZipPath) == FALSE) { BYTE bin[] = { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; FILE* fp; if (_tfopen_s(&fp, ZipPath, _TEXT("wb"))) { MessageBox(NULL, _TEXT("ZIPファイルが作成できませんでした。"), _TEXT("エラー"), MB_ICONWARNING); VariantClear(&vSrcFile); return FALSE; } fwrite(bin, sizeof(bin), 1, fp); fclose(fp); } // ZIPファイルのFolderオブジェクトを作成 VARIANT vZip; Folder* pZipFile; VariantInit(&vZip); vZip.vt = VT_BSTR; vZip.bstrVal = SysAllocString(ZipPath); hr = pShellDisp->NameSpace(vZip, &pZipFile); VariantClear(&vZip); if (hr != S_OK) { VariantClear(&vSrcFile); pZipFile->Release(); MessageBox(NULL, _TEXT("ZIPファイルが見つかりませんでした。"), _TEXT("エラー"), MB_ICONWARNING); return FALSE; } VARIANT varOpt; // 兄弟スレッド、子スレッドの数を取得 DWORD ThreadOldCount = 0; HANDLE h; h = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); if (h != INVALID_HANDLE_VALUE) { THREADENTRY32 te; te.dwSize = sizeof(te); if (Thread32First(h, &te)) { do { if ((te.th32OwnerProcessID == GetCurrentProcessId()) && (te.th32ThreadID != GetCurrentThreadId())) { _tprintf(_TEXT("追加前 %i プロセルID 0x%04x スレッドID 0x%04x¥n"), ThreadOldCount, te.th32OwnerProcessID, te.th32ThreadID); ThreadOldCount++; } te.dwSize = sizeof(te); } while (Thread32Next(h, &te)); } CloseHandle(h); } // ZIPへファイルをコピー VariantInit(&varOpt); varOpt.vt = VT_I4; varOpt.lVal = 0;// FOF_SILENTを指定すると処理中の経過が表示されなくなります hr = pZipFile->CopyHere(vSrcFile, varOpt); if (hr != S_OK) { pZipFile->Release(); VariantClear(&vSrcFile); MessageBox(NULL, _TEXT("ファイルを追加できませんでした。"), _TEXT("エラー"), MB_ICONWARNING); return FALSE; } Sleep(100); if (hr == S_OK) { /* 兄弟スレッド、子スレッドの数を取得し最後に見つかったスレッドを コピースレッドとみなし終了するまで待機する*/ HANDLE hThread = 0; DWORD ThreadNewCount = 0; DWORD ThreadMax = 0; DWORD n; h = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0); if (h != INVALID_HANDLE_VALUE) { THREADENTRY32 te; DWORD ThreadID; HANDLE hThreads[8]; te.dwSize = sizeof(te); if (Thread32First(h, &te)) { do { if ((te.th32OwnerProcessID == GetCurrentProcessId()) && (te.th32ThreadID != GetCurrentThreadId())) { if (ThreadOldCount <= ThreadNewCount) {//追加されたスレッド hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID); hThreads[ThreadMax++] = hThread; if (ThreadMax == sizeof(hThreads) / sizeof(hThreads[0])) { for (n = 0; n < ThreadMax; n++) CloseHandle(hThreads[n]); pZipFile->Release(); MessageBox(NULL, _TEXT("スレッド数がオーバーしました。"), _TEXT("エラー"), MB_ICONWARNING); return FALSE; } _tprintf(_TEXT("Copy-")); } _tprintf(_TEXT("追加後 %i プロセルID 0x%04x スレッドID 0x%04x¥n"), ThreadNewCount, te.th32OwnerProcessID, ThreadID = te.th32ThreadID); ThreadNewCount++; } te.dwSize = sizeof(te); } while (Thread32Next(h, &te)); } CloseHandle(h); if (ThreadOldCount + 1 <= ThreadNewCount) // 最後に追加されたスレッドが終了するまで待機 WaitForMultipleObjects(ThreadMax, hThreads, TRUE, INFINITE); for (n = 0; n < ThreadMax; n++) CloseHandle(hThreads[n]); } } pZipFile->Release(); VariantClear(&vSrcFile); return TRUE; } // プログラムの実行: Ctrl + F5 または [デバッグ] > [デバッグなしで開始] メニュー // プログラムのデバッグ: F5 または [デバッグ] > [デバッグの開始] メニュー // 作業を開始するためのヒント: // 1. ソリューション エクスプローラー ウィンドウを使用してファイルを追加/管理します // 2. チーム エクスプローラー ウィンドウを使用してソース管理に接続します // 3. 出力ウィンドウを使用して、ビルド出力とその他のメッセージを表示します // 4. エラー一覧ウィンドウを使用してエラーを表示します // 5. [プロジェクト] > [新しい項目の追加] と移動して新しいコード ファイルを作成するか、[プロジェクト] > [既存の項目の追加] と移動して既存のコード ファイルをプロジェクトに追加します // 6. 後ほどこのプロジェクトを再び開く場合、[ファイル] > [開く] > [プロジェクト] と移動して .sln ファイルを選択します