After a long search I found one hope in Folder::CopyHere() to copy files/folder to a zip file, without using any third party utilities.
However now my concern is on hiding the 'Compressing' progress dialog while copying to a zip file.
My dialog show my own custom progress dialog, so I don not want to display windows default progress bar.
Event after using FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR flags I am not able to hide the 'Compressing' progress dialog. But yes the progress dialog isnot displayed if my destination is a folder.
Is it a known issue or exists any solution or any alternative methods( other than 3rd parties).
My code snippet is shared below:
Code flow
OnBnClickedButtonZip() -> CreateEmptyZipFile()
-> ZipFile() // Calls CopyHere API and Waits for completion
-> MyThreadProc() // signals ZipFile() when completed
struct STR
{
Folder* pToFolder;
int nCount;
};
void CzipunzipDlg::OnBnClickedButtonZip()
{
CreateEmptyZipFile( L"D:\\Sample.zip");
CStringArray strSrcArray;
strSrcArray.Add(L"D:\\Test1");
strSrcArray.Add(L"D:\\Test2");
CString csDest = L"D:\\Sample.zip";
ResetEvent(m_hEvtHandle);
ZipFile( strSrcArray , csDest );
AfxMessageBox(L"Completed");
}
void CzipunzipDlg::CreateEmptyZipFile(CString strPath)
{
BYTE startBuffer[] = {80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
FILE *f = _wfopen(strPath.GetBuffer(strPath.GetLength()), _T("wb"));
strPath.ReleaseBuffer();
fwrite(startBuffer,sizeof(startBuffer),1,f);
fclose(f);
}
void CzipunzipDlg::ZipFile(CStringArray& strSrcArray, CString& strDest)
{
HRESULT hResult = S_FALSE;
IShellDispatch *pIShellDispatch = NULL;
Folder *pToFolder = NULL;
VARIANT variantDir, variantFile, variantOpt;
CoInitialize(NULL);
hResult = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, IID_IShellDispatch, (void **)&pIShellDispatch);
BSTR bstrDest = strDest.AllocSysString();
if (SUCCEEDED(hResult))
{
VariantInit(&variantDir);
variantDir.vt = VT_BSTR;
variantDir.bstrVal = bstrDest;
hResult = pIShellDispatch->NameSpace(variantDir, &pToFolder);
if (SUCCEEDED(hResult))
{
int nTotalFileCount = strSrcArray.GetSize();
for( int i = 0; i < nTotalFileCount; ++i )
{
BSTR bstrSource = strSrcArray[i].AllocSysString();
VariantInit(&variantFile);
variantFile.vt = VT_BSTR;
variantFile.bstrVal = bstrSource;
VariantInit(&variantOpt);
variantOpt.vt = VT_I4;
variantOpt.lVal = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NOCONFIRMMKDIR;
hResult = pToFolder->CopyHere(variantFile, variantOpt);
STR str;
str.nCount = i + 1;
str.pToFolder = pToFolder;
CWinThread* pThread = AfxBeginThread( CzipunzipDlg::MyThreadProc, &str );
DWORD dwResult = WaitForSingleObject( pThread->m_hThread, INFINITE );
}
pToFolder->Release();
}
pIShellDispatch->Release();
}
CoUninitialize();
}
UINT CzipunzipDlg::MyThreadProc( LPVOID lParam_i )
{
CoInitialize(NULL);
STR* str = reinterpret_cast<STR*>( lParam_i );
long lFileCount = 0;
FolderItems *pFolderItems = NULL;
do
{
HRESULT hResult = str->pToFolder->Items( &pFolderItems );
hResult = pFolderItems->get_Count( &lFileCount);
Sleep(100);
}while( str->nCount != lFileCount );
HANDLE hAhndle = OpenEvent(EVENT_ALL_ACCESS, FALSE, ZIP_EVENT );
SetEvent( hAhndle );
return 0;
}
My development environment is VS2008 and Windows 7 Enterprise.