プログラミングメモ →目次

shell32.dllでファイル圧縮(VC++)

windows\system32\にあるshell32.dllにあるShell.Applicationを利用して、ファイルを圧縮して、zipファイルに保存することができます。
例として、Dドライブのルートフォルダに、空のzipファイルのc.zipを作ってから、a.txtとb.txtをc.zipに入れます。


#<import> 

void CreateEmptyZipFile(LPCTSTR lpszPathname)
{
   char chEmpty[] = {'P','K',5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
        
    CFile fileEmpty;
    fileEmpty.Open(lpszPathname, CFile::modeWrite | CFile::modeCreate);
    fileEmpty.Write(chEmpty, sizeof(chEmpty));
    fileEmpty.Close();
}

BOOL FileExist(LPCTSTR lpszPathname)
{
    CFileFind find;
    return find.FindFile( lpszPathname );
}

CString GetFilename(LPCTSTR lpszPathname)
{
    CFileFind find;
    if (find.FindFile(lpszPathname))
	{
		find.FindNextFile();
		return find.GetFileName();
	}
	else
		return "";
}

HRESULT AddFileToZipFile(LPCTSTR lpszZipPathname, LPCTSTR lpszFilePathname)
{
	if (!FileExist(lpszZipPathname))
		CreateEmptyZipFile(lpszZipPathname);

	if (!FileExist(lpszFilePathname))
		return S_FALSE;

	CString strFilename = GetFilename(lpszFilePathname);

	HRESULT hRes = S_FALSE;
    Shell32::IShellDispatchPtr ptrShell;
	hRes = ptrShell.CreateInstance(__uuidof(Shell32::Shell));
	if ( hRes == S_OK)
	{
		Shell32::FolderPtr ptrFolder=ptrShell->NameSpace((COleVariant)lpszZipPathname);
		if (ptrFolder)
		{
			Shell32::FolderItemPtr ptrFolderItem = ptrFolder->ParseName((LPCTSTR)strFilename);
			if (ptrFolderItem)
			{
				int iCountBeforeDelete = ptrFolder->Items()->GetCount();
				ptrFolderItem->InvokeVerb((COleVariant)"delete");
				TRACE("<%s> exists. Deleted it.\r\n", strFilename);
				ptrFolderItem.Release();
				ptrFolderItem = NULL;
				int iCountAfterDelete = ptrFolder->Items()->GetCount();
	
				if (iCountAfterDelete == iCountBeforeDelete)
				{
					ptrFolder.Release();
					ptrFolder = NULL;
					ptrShell.Release(); 
					ptrShell = NULL; 
					return S_OK;
				}
			}

			long iDat = FOF_SILENT | FOF_NOCONFIRMATION;
			int iCountBeforeCopy = ptrFolder->Items()->GetCount();
			hRes = ptrFolder->CopyHere((COleVariant)lpszFilePathname, (COleVariant)iDat);
			int i= 0;

			while(1)
			{
				int iCountAfterCopy = ptrFolder->Items()->GetCount();
				TRACE("CountAfterCopy = %d, CountBeforeCopy = %d   ...\r\n", iCountAfterCopy, iCountBeforeCopy);
				if ( iCountAfterCopy > iCountBeforeCopy)
					break;
				Sleep(100);

			}
			ptrFolder.Release();
			ptrFolder = NULL;
		}
		ptrShell.Release(); 
		ptrShell = NULL; 
	}
	return hRes;
}


void ZipTest(void) 
{  

	HRESULT hRes = CoInitialize(NULL);
	AddFileToZipFile("d:\\b.zip", "d:\\a.txt");
	CoUninitialize( );
}