başka yerde açıklamalarda belirtildiği gibi, bu sadece bir önceden oluşturulan Zip dosyası üzerinde çalışacak. İçerik, zip dosyasında da bulunmamalı veya bir hata görüntülenecektir. İşte kabul edilen cevaba dayanarak oluşturduğum örnek örnek kod. Shell32.lib ve ayrıca kernel32.lib (CreateToolhelp32Snapshot için) bağlantı kurmanız gerekir.Ben sonra daha fazla araştırma beri, yarı fonksiyonel kodu alma rağmen bu yoldan gitmeye karar verdik
#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;
}
, Klasör görünür :: CopyHere() yöntemi aslında sizi, yani kendisine geçirilen VOptions saygı duymayan dosyaları üzerine yazmaya zorlamaz veya kullanıcıya hata diyaloglarını gösteremez.
Bunun ışığında, başka bir posterin de bahsettiği XZip kütüphanesini denedim. Bu kitaplık bir Zip arşivi oluşturmak için iyi çalışır, ancak ZIP_FOLDER ile çağrılan ZipAdd() işlevinin özyineli olmadığını unutmayın - yalnızca arşivde bir klasör oluşturur. Bir arşivi yinelemek için AddFolderContent() işlevini kullanmanız gerekir. Örneğin, bir C oluşturmak için: \ Sample.zip ve C ekleyin:
HZIP newZip = CreateZip("C:\\Sample.zip", NULL, ZIP_FILENAME);
BOOL retval = AddFolderContent(newZip, "C:", "temp");
Önemli not: buna \ Temp klasörünü, aşağıdaki kullanmak XZip dahil olarak AddFolderContent() fonksiyonu işlevsel değil kütüphane. Dizin yapısına yeniden girer ancak ZipAdd() 'a geçirilen yollardaki bir hata nedeniyle, zip arşivine herhangi bir dosya eklemeyi başaramaz. olarak, bozuldu
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)
Windows'da Win32 API kullanarak sıkıştırılmış bir klasör nasıl oluşturulur: http://ixmx.wordpress.com/2009/09/16/how-to-create-a-compress-folder-in-windows-using-win32 -api/ – anno
Shell32.CopyHere'i C veya C++'dan kullanabilirsiniz, yalnızca COM nesnesini başlatmak için gerekli win32 API'lerini çağırın. – Motes