के रूप में टिप्पणी में कहीं उल्लेख किया, यह केवल एक पहले से ही बनाया ज़िप फ़ाइल पर काम करेंगे। सामग्री को ज़िप फ़ाइल में पहले से मौजूद नहीं होना चाहिए, या एक त्रुटि प्रदर्शित की जाएगी। यहां काम करने वाला नमूना कोड है जिसे मैं स्वीकार किए गए उत्तर के आधार पर बनाने में सक्षम था। आपको shell32.lib और kernel32.lib (CreateToolhelp32 स्नैपशॉट के लिए) से लिंक करने की आवश्यकता है।
#include <windows.h>
#include <shldisp.h>
#include <tlhelp32.h>
#include <stdio.h>
int main(int argc, TCHAR* argv[])
{
DWORD strlen = 0;
char szFrom[] = "C:\\Temp",
szTo[] = "C:\\Sample.zip";
HRESULT hResult;
IShellDispatch *pISD;
Folder *pToFolder = NULL;
VARIANT vDir, vFile, vOpt;
BSTR strptr1, strptr2;
CoInitialize(NULL);
hResult = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **)&pISD);
if (SUCCEEDED(hResult) && pISD != NULL)
{
strlen = MultiByteToWideChar(CP_ACP, 0, szTo, -1, 0, 0);
strptr1 = SysAllocStringLen(0, strlen);
MultiByteToWideChar(CP_ACP, 0, szTo, -1, strptr1, strlen);
VariantInit(&vDir);
vDir.vt = VT_BSTR;
vDir.bstrVal = strptr1;
hResult = pISD->NameSpace(vDir, &pToFolder);
if (SUCCEEDED(hResult))
{
strlen = MultiByteToWideChar(CP_ACP, 0, szFrom, -1, 0, 0);
strptr2 = SysAllocStringLen(0, strlen);
MultiByteToWideChar(CP_ACP, 0, szFrom, -1, strptr2, strlen);
VariantInit(&vFile);
vFile.vt = VT_BSTR;
vFile.bstrVal = strptr2;
VariantInit(&vOpt);
vOpt.vt = VT_I4;
vOpt.lVal = 4; // Do not display a progress dialog box
hResult = NULL;
printf("Copying %s to %s ...\n", szFrom, szTo);
hResult = pToFolder->CopyHere(vFile, vOpt); //NOTE: this appears to always return S_OK even on error
/*
* 1) Enumerate current threads in the process using Thread32First/Thread32Next
* 2) Start the operation
* 3) Enumerate the threads again
* 4) Wait for any new threads using WaitForMultipleObjects
*
* Of course, if the operation creates any new threads that don't exit, then you have a problem.
*/
if (hResult == S_OK) {
//NOTE: hard-coded for testing - be sure not to overflow the array if > 5 threads exist
HANDLE hThrd[5];
HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPALL ,0); //TH32CS_SNAPMODULE, 0);
DWORD NUM_THREADS = 0;
if (h != INVALID_HANDLE_VALUE) {
THREADENTRY32 te;
te.dwSize = sizeof(te);
if (Thread32First(h, &te)) {
do {
if (te.dwSize >= (FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID))) {
//only enumerate threads that are called by this process and not the main thread
if((te.th32OwnerProcessID == GetCurrentProcessId()) && (te.th32ThreadID != GetCurrentThreadId())){
//printf("Process 0x%04x Thread 0x%04x\n", te.th32OwnerProcessID, te.th32ThreadID);
hThrd[NUM_THREADS] = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID);
NUM_THREADS++;
}
}
te.dwSize = sizeof(te);
} while (Thread32Next(h, &te));
}
CloseHandle(h);
printf("waiting for all threads to exit...\n");
//Wait for all threads to exit
WaitForMultipleObjects(NUM_THREADS, hThrd , TRUE , INFINITE);
//Close All handles
for (DWORD i = 0; i < NUM_THREADS ; i++){
CloseHandle(hThrd[i]);
}
} //if invalid handle
} //if CopyHere() hResult is S_OK
SysFreeString(strptr2);
pToFolder->Release();
}
SysFreeString(strptr1);
pISD->Release();
}
CoUninitialize();
printf ("Press ENTER to exit\n");
getchar();
return 0;
}
मैं अर्द्ध कार्यात्मक कोड हो रही है, के बाद आगे की जांच पड़ताल के बाद के बावजूद इस मार्ग से जाने के लिए नहीं करने का फैसला किया है, यह फ़ोल्डर प्रकट होता है :: CopyHere() विधि वास्तव में vOptions इसे करने के लिए पारित किया सम्मान नहीं करता है, जो आप का मतलब फ़ाइलों को ओवरराइट करने या उपयोगकर्ता को त्रुटि संवाद प्रदर्शित करने के लिए मजबूर नहीं कर सकता है।
उस के प्रकाश में, मैंने एक अन्य पोस्टर द्वारा वर्णित XZip लाइब्रेरी की भी कोशिश की। यह लाइब्रेरी ज़िप संग्रह बनाने के लिए ठीक काम करती है, लेकिन ध्यान दें कि ज़िप_फॉल्डर के साथ बुलाया गया ZipAdd() फ़ंक्शन रिकर्सिव नहीं है - यह केवल संग्रह में एक फ़ोल्डर बनाता है। एक संग्रह को दोबारा ज़िप करने के लिए आपको AddFolderContent() फ़ंक्शन का उपयोग करने की आवश्यकता होगी। उदाहरण के लिए, एक सी बनाने के लिए: \ Sample.zip और सी जोड़ें:
HZIP newZip = CreateZip("C:\\Sample.zip", NULL, ZIP_FILENAME);
BOOL retval = AddFolderContent(newZip, "C:", "temp");
महत्वपूर्ण नोट:: यह करने के लिए \ अस्थायी फ़ोल्डर, निम्न का उपयोग XZip में शामिल के रूप में AddFolderContent() फ़ंक्शन कार्यात्मक नहीं है पुस्तकालय। यह निर्देशिका संरचना में पुन: कार्य करेगा लेकिन ZipAdd() को पारित पथों में एक बग के कारण ज़िप संग्रह में कोई भी फाइल जोड़ने में विफल रहता है।
if (ZipAdd(hZip, RelativePathNewFileFound, RelativePathNewFileFound, 0, ZIP_FILENAME) != ZR_OK)
निम्नलिखित करने के लिए::
ZRESULT ret;
TCHAR real_path[MAX_PATH] = {0};
_tcscat(real_path, AbsolutePath);
_tcscat(real_path, RelativePathNewFileFound);
if (ZipAdd(hZip, RelativePathNewFileFound, real_path, 0, ZIP_FILENAME) != ZR_OK)
Win32 API का उपयोग कर Windows में संपीड़ित फ़ोल्डर कैसे बनाएं: http://ixmx.wordpress.com/2009/09/16/how-to-create-a-compress-folder-in-windows-using-win32 -पीआई/ – anno
आप सी या सी ++ से Shell32.CopyHere का उपयोग कर सकते हैं, COM ऑब्जेक्ट को तुरंत चालू करने के लिए केवल आवश्यक Win32 API को कॉल करें। – Motes