首页 > 代码库 > 安装包设计-------打包(MFC)---------知识总结
安装包设计-------打包(MFC)---------知识总结
目录:
1、选择文件夹
2、判断文件夹或文件是否存在
3、通过cmd命令行向程序中传递参数。
4、路径处理
5、文件夹以及文件的删除
6、复制文件
7、创建目录
8、从当前的应用程序中抽取资源
9、引用的别人的抽取等程序
10、压缩解压,引用别人的
11、添加资源到工程中
实现:
1、选择文件夹
CDirDialog dlg; dlg.SetWindowTitle(_T("选择待打包文件夹")); if(dlg.DoModal() == IDOK) { CString Path = dlg.GetPathname(); CString m_selectdir = Path; }
2、判断文件夹或文件是否存在
BOOL FolderExist(CString& strPath) //strPath 文件夹路径 { CString sCheckPath = strPath; if(sCheckPath.Right(1) != L"/") { sCheckPath += L"/"; } sCheckPath += L"*.*"; WIN32_FIND_DATA wfd; BOOL rValue = FALSE; HANDLE hFind = FindFirstFile(sCheckPath, &wfd); if ((hFind!=INVALID_HANDLE_VALUE) && (wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) ||(wfd.dwFileAttributes&FILE_ATTRIBUTE_ARCHIVE)) { //如果存在并类型是文件夹 rValue = TRUE; } FindClose(hFind); return rValue; }
3、通过cmd命令行向程序中传递参数
在命令行窗口输入: Package.exe 文件名 版本号
__argc = 3;
__argv[0]="Package.exe";__argv[1]="文件名";__argv[2]="版本号";
4、路径处理
在windows平台上获得的路径一般是这种形式:c:\Test\demo.exe,是以\来区分目录级别,linux平台上是不能识别这种形式的路径,只能识别c:/Test/demo.exe,这一种形式,windows也识别这种形式。所以在以后的路径处理上要使用c:/Test/demo.exe这种形式。
5、文件夹以及文件的删除
CFile::Remove(LPCTSTR lpszFileName, CAtlTransactionManager* pTM) 删除单个文件,但在实际过程中需要删除当前目录以及目录下的所有文件。
bool MyDeleteFile(CString &Path) { SHFILEOPSTRUCT FileOp={0}; FileOp.fFlags = FOF_ALLOWUNDO | //允许放回回收站 FOF_NOCONFIRMATION; //不出现确认对话框 FileOp.pFrom = Path; FileOp.pTo = NULL; //一定要是NULL FileOp.wFunc = FO_DELETE; //删除操作 return SHFileOperation(&FileOp) == 0; }
6、复制文件
CopyFile(LPCTSTR lpExistingFileName,LPCTSTR lpNewFileName,BOOL bFailIfExists) bFailIfExists=false时,如果文件已经存在则覆盖文件。
7、创建目录
bool CreateDir(CString strPath) { char* temp=strPath.GetBuffer(strPath.GetLength()); std::string Directoryname = temp; if (Directoryname[Directoryname.length() - 1] != ‘\\‘) { Directoryname.append(1, ‘\\‘); } std::vector< std::string> vpath; std::string strtemp; BOOL bSuccess = FALSE; for (int i = 0; i < Directoryname.length(); i++) { if ( Directoryname[i] != ‘\\‘) { strtemp.append(1,Directoryname[i]); } else { vpath.push_back(strtemp); strtemp.append(1, ‘\\‘); } } std::vector<std::string>:: const_iterator vIter; for (vIter = vpath.begin();vIter != vpath.end(); vIter++) { bSuccess = CreateDirectory(vIter->c_str(), NULL) ? TRUE :FALSE; } return true; }
8、从当前的应用程序中抽取资源
bool GetResourceFromLocal(CString &DesPath) { //从本地应用获得资源文件.zip CString tempPathPro = DesPath + "/" + "Resource.zip"; //输出路径 HRSRC hrSrc = http://www.mamicode.com/FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_AFX_RESOURCE), "AFX_RESOURCE"); if(hrSrc =http://www.mamicode.com/= NULL) { return false; } HGLOBAL hGlobal = LoadResource(AfxGetResourceHandle(), hrSrc); if(hGlobal == NULL) { return false; } LPVOID lpExe = LockResource(hGlobal); if(lpExe == NULL) { return false; } CFile file; if(!file.Open(tempPathPro, CFile::modeCreate | CFile::modeWrite)) { return false; } else { file.Write(lpExe, (UINT)SizeofResource(AfxGetResourceHandle(), hrSrc)); file.Close(); } return true; }
9、引用的别人的抽取等程序
/************************************************************************************* * * File: SEFileInfo.cpp * Version: 1.0 * * Author: James Spibey * Date: 04/08/1999 * E-mail: spib@bigfoot.com * * Implementation of the CSEFileInfo class * * You are free to use, distribute or modify this code * as long as this header is not removed or modified. * * *************************************************************************************/ #include "stdafx.h" #include "SEFileInfo.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif /******************************************************************************* * * Function: CSEFileInfo::CSEFileInfo * * Description: * Default Constructor * * Parameters: * None * * Return: * None *******************************************************************************/ CSEFileInfo::CSEFileInfo() { Reset(); } /******************************************************************************* * * Function: CSEFileInfo::~CSEFileInfo * * Description: * Destructor * * Parameters: * None * * Return: * None *******************************************************************************/ CSEFileInfo::~CSEFileInfo() { } /******************************************************************************* * * Function: CSEFileInfo::SetData * * Description: *Set the data members for the class * * Parameters: * CString Filename: Filename of file to gather data about * * Return: * BOOL : Success or Failure *******************************************************************************/ BOOL CSEFileInfo::SetData(CString Filename) { CFile f; //Open the file if(!f.Open(Filename, CFile::modeRead)) return FALSE; //Get the length in bytes m_nSize = f.GetLength(); f.Close(); m_strPathname = Filename; m_strFilename = Filename.Mid(Filename.ReverseFind(‘/‘) + 1); return TRUE; } /******************************************************************************* * * Function: CSEFileInfo::Reset * * Description: * Reset the class data members * * Parameters: * None * * Return: * None *******************************************************************************/ void CSEFileInfo::Reset() { m_nSize = 0; m_strPathname = ""; m_strFilename = ""; }
/************************************************************************************* * * File: SelfExtracter.cpp * Version: 1.0 * * Author: James Spibey * Date: 04/08/1999 * E-mail: spib@bigfoot.com * * Implementation of the CSelfExtracter class * * You are free to use, distribute or modify this code * as long as this header is not removed or modified. * * *************************************************************************************/ #include "stdafx.h" #include "SelfExtractor.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif /******************************************************************************* * * Function: CSelfExtractor::CSelfExtractor * * Description: * Default Constructor * * Parameters: * None * * Return: * None *******************************************************************************/ CSelfExtractor::CSelfExtractor() { m_nFiles = 0; m_nTOCSize = 0; } /******************************************************************************* * * Function: CSelfExtractor::~CSelfExtractor * * Description: * Destructor * * Parameters: * None * * Return: * None *******************************************************************************/ CSelfExtractor::~CSelfExtractor() { } bool CSelfExtractor::GetResource(UINT resource, CString &Filename ) { if(m_nFiles < 1) return false; //Load the extractor from resources HRSRC hrSrc = http://www.mamicode.com/FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(resource), "AFX_EXE"); if(hrSrc =http://www.mamicode.com/= NULL) return false; HGLOBAL hGlobal = LoadResource(AfxGetResourceHandle(), hrSrc); if(hGlobal == NULL) return false; LPVOID lpExe = LockResource(hGlobal); if(lpExe == NULL) return false; //Create the new archive from the extractor in the resources CFile file; if(!file.Open(Filename, CFile::modeCreate | CFile::modeWrite)) return false; else { //Write the extractor exe file.Write(lpExe, (UINT)SizeofResource(AfxGetResourceHandle(), hrSrc)); file.Close(); } } /******************************************************************************* * * Function: CSelfExtractor::Create * * Description: * Creates the Self-extracting executable * * Parameters: * CString ExtractorPath: Path to the Extractor Executable * CString Filename: Filename of the Self Extracting Archive to create * funcPtr pFn: Pointer to a user defined callback function * void* UserData: User defined data to pass to the callback function * * Return: * int: Error Code * NOTHING_TO_DO - No files have been selected to be archived * COPY_FAILED - Failed to copy the extractor * OUTPUT_FILE_ERROR - Failed to open the copied file for appending * INPUT_FILE_ERROR - Failed to open an input file *******************************************************************************/ int CSelfExtractor::Create(CString ExtractorPath, CString Filename, funcPtr pFn /* = NULL */, void* userData /*=NULL*/) { //Make sure we have some files to add if(m_nFiles < 1) return NOTHING_TO_DO; //Copy the extractor to the new archive CShellFileOp shOp; shOp.SetFlags(FOF_FILESONLY | FOF_NOCONFIRMATION | FOF_SILENT); shOp.AddFile(SH_SRC_FILE, ExtractorPath); shOp.AddFile(SH_DEST_FILE, Filename); if(shOp.CopyFiles() != 0) return COPY_FAILED; //Open the archive CFile file; if(!file.Open(Filename, CFile::modeWrite)) return OUTPUT_FILE_ERROR; else { //Start at the end of the archive file.SeekToEnd(); CreateArchive(&file, pFn, userData); //Close the archive file.Close(); } return SUCCESS; } /******************************************************************************* * * Function: CSelfExtractor::Create * * Description: * Creates the Self-extracting executable from an extractor in resources. * Simply import the exe into your resources, making sure you specify the type * as "SFX_EXE". Then just past the resource ID as the first parameter * * Parameters: * UINT resource: Resource ID (eg IDR_SFX_EXE) * CString Filename: Filename of the Self Extracting Archive to create * funcPtr pFn: Pointer to a user defined callback function * void* UserData: User defined data to pass to the callback function * * Return: * int: Error Code * NOTHING_TO_DO - No files have been selected to be archived * COPY_FAILED - Failed to copy the extractor * OUTPUT_FILE_ERROR - Failed to open the copied file for appending * INPUT_FILE_ERROR - Failed to open an input file *******************************************************************************/ int CSelfExtractor::Create(UINT resource, CString Filename, funcPtr pFn /* = NULL */, void* userData /*=NULL*/) { //Make sure we have some files to add /*if(m_nFiles < 1) return NOTHING_TO_DO; //Load the extractor from resources HRSRC hrSrc = http://www.mamicode.com/FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(resource),"AFX_EXE"); if(hrSrc =http://www.mamicode.com/= NULL)>*/ //Create the new archive from the extractor in the resources CFile file; if(!file.Open(Filename, CFile::modeWrite)) return OUTPUT_FILE_ERROR; else { //Write the extractor exe //file.Write(lpExe, (UINT)SizeofResource(AfxGetResourceHandle(), hrSrc)); //Do the rest CreateArchive(&file, pFn, userData); //Close the archive file.Close(); } return SUCCESS; } int CSelfExtractor::CreateArchive(CFile* pFile, funcPtr pFn, void* userData) { DWORD dwRead = 0; //Total Data read from input file DWORD dw = 0; //Last amount read from input file char buffer[1000]; //Buffer for data CFile data; //Input file try { pFile->SeekToEnd(); //Copy all the inout files into the archive for(int i = 0; i < m_nFiles; i++) { //Open the input file if(data.Open(m_InfoArray[i].GetPathname(), CFile::modeRead)) { dwRead = 0; m_InfoArray[i].SetOffset(pFile->GetPosition()); //Read data in and write it out until the end of file while(static_cast<int>(dwRead) < m_InfoArray[i].GetFileSize()) { dw = data.Read(buffer, 1000); pFile->Write(buffer, dw); dwRead += dw; } //Close this input file data.Close(); //Call the user defined CallBack if(pFn != NULL) pFn(static_cast<void*>(&m_InfoArray[i]), userData); } else return INPUT_FILE_ERROR; } //Now Write the TOC for(int j = 0; j < m_nFiles; j++) { //Write the File Size int Offset = m_InfoArray[j].GetFileOffset(); pFile->Write(&Offset, sizeof(int)); //Write the File Size int len = m_InfoArray[j].GetFileSize(); pFile->Write(&len, sizeof(int)); //Write the filename len = m_InfoArray[j].GetFilename().GetLength(); strncpy(buffer, m_InfoArray[j].GetFilename(), len); pFile->Write(buffer, len); //Write the length of the filename pFile->Write(&len, sizeof(int)); } //Write the total number of files pFile->Write((void*)&m_nFiles, sizeof(int)); //Write the SIG strcpy(buffer, SIGNATURE); pFile->Write(buffer, strlen(SIGNATURE)); } catch(CFileException* e) { //Got sick of seeing ‘unreferenced local variable‘ e->m_cause; return OUTPUT_FILE_ERROR; } } /******************************************************************************* * * Function: CSelfExtractor::ExtractAll * * Description: * Extract the current archive to the specified directory * * Parameters: * CString Dir: Destination Directory * funcPtr pFn: Pointer to a user defined callback function * void* UserData: User defined data to pass to the callback function * * Return: * int: Error Code * INPUT_FILE_ERROR - Failed to open the input file * OUTPUT_FILE_ERROR - Failed to create an output file *******************************************************************************/ int CSelfExtractor::ExtractAll(CString Dir, funcPtr pFn /*= NULL*/, void * userData /*= NULL*/) { //Make sure the directory name has a trailing backslash EnsureTrailingBackSlash(Dir); CFile Thisfile; //Archive (Usually itself) //Read the Table of Contents int res = ReadTOC(GetThisFileName()); if(res != SUCCESS) return res; //Open the archive if(!Thisfile.Open(GetThisFileName(), CFile::modeRead)) return INPUT_FILE_ERROR; else { //Get the files out in reverse order so we can work out the offsets //Subtract 1 from the filecount as we are zero-based for(int i = (m_nFiles - 1); i >= 0 ; i--) { ExtractOne(&Thisfile, i, Dir); //Do the callback if(pFn != NULL) pFn(static_cast<void*>(&m_InfoArray[i]), userData); } //Close the archive Thisfile.Close(); } return SUCCESS; } /******************************************************************************* * * Function: CSelfExtractor::Extract * * Description: * Extract a single file from the current archive to the specified directory * * Parameters: * int index: index in array of file * CString Dir: Destination Directory * * Return: * int: Error Code * INPUT_FILE_ERROR - Failed to open the input file * OUTPUT_FILE_ERROR - Failed to create an output file *******************************************************************************/ int CSelfExtractor::Extract(int index, CString Dir) { //Make sure the directory name has a trailing backslash EnsureTrailingBackSlash(Dir); CFile Thisfile; //Archive (Usually itself) //Read the Table of Contents int res = ReadTOC(GetThisFileName()); if(res != SUCCESS) return res; //Open the archive if(!Thisfile.Open(GetThisFileName(), CFile::modeRead)) return INPUT_FILE_ERROR; else { ExtractOne(&Thisfile, index, Dir); //Close the archive Thisfile.Close(); } return SUCCESS; } /******************************************************************************* * * Function: CSelfExtractor::ExtractOne * * Description: * Actual Data Extraction. Seeks to required offset in archive * and writes new file * * Parameters: * CFile* file: Pointer to the archive * int index: Index of file in array * CString Dir: Destination Dir * * Return: * int: Error Code *******************************************************************************/ int CSelfExtractor::ExtractOne(CFile* file, int index, CString Dir) { char buffer[1000]; //Buffer to read and write with CFile NewFile; //Extracted File //Get the file size (in bytes) int FileSize = m_InfoArray[index].GetFileSize(); //Create the new file if(!NewFile.Open(Dir + m_InfoArray[index].GetFilename() , CFile::modeCreate | CFile::modeWrite)) return OUTPUT_FILE_ERROR; //Seek to the correct Offset file->Seek(m_InfoArray[index].GetFileOffset(), CFile::begin); //Loop the data out from the archive DWORD dwWritten = 0; DWORD dwRead = 0; int AmountToRead = 0; while(TRUE) { //Read out 1000 bytes at a time or the remainder if //there is less than 1000 left. Exit if there is none left AmountToRead = FileSize - dwWritten; if(AmountToRead > 1000) AmountToRead = 1000; else if(AmountToRead == 0) break; dwRead = file->Read(buffer, AmountToRead); NewFile.Write(buffer, dwRead); dwWritten += dwRead; } //Close the output file NewFile.Close(); return SUCCESS; } /******************************************************************************* * * Function: CSelfExtractor::ReadTOC * * Description: * Read the archive‘s Table of Contents * * Parameters: * CString Filename: Filename of the archive (full path) * * Return: * int: Error Code *******************************************************************************/ int CSelfExtractor::ReadTOC(CString Filename) { CFile Thisfile; //Archive file char buffer[1000]; //Buffer to read and write with //Clear the CSEFileInfo class array Reset(); //Open the archive if(!Thisfile.Open(Filename, CFile::modeRead)) return NO_SOURCE; else { //Read in the signature Thisfile.Seek(- static_cast<int>(strlen(SIGNATURE)), CFile::end); Thisfile.Read(buffer, strlen(SIGNATURE)); //Check that it matches if(strncmp(buffer, SIGNATURE, strlen(SIGNATURE)) != 0) return INVALID_SIG; else { //Read Number of files int LastOffset = strlen(SIGNATURE) + static_cast<int>(sizeof(int)); Thisfile.Seek(-LastOffset, CFile::end); Thisfile.Read(&m_nFiles, sizeof(int)); //If there are no files in the archive, there is nothing to extract if(m_nFiles == 0) return NOTHING_TO_DO; //Read the TOC in. The array is filled in reverse to ensure that it //corresponds to the data segment for(int i = (m_nFiles - 1); i >= 0 ; i--) { int nSize = 0; int nOffset = 0; int len = 0; LastOffset += sizeof(int); //Get Length of Pathname Thisfile.Seek(-LastOffset, CFile::end); Thisfile.Read(&len, sizeof(int)); LastOffset += len; //Get Path Name Thisfile.Seek(-LastOffset, CFile::end); Thisfile.Read(buffer, len); LastOffset += sizeof(int); //Get File Size Thisfile.Seek(-LastOffset, CFile::end); Thisfile.Read(&nSize, sizeof(int)); LastOffset += sizeof(int); //Get File Offset Thisfile.Seek(-LastOffset, CFile::end); Thisfile.Read(&nOffset, sizeof(int)); //Set the data in the array m_InfoArray[i].SetSize(nSize); CString Temp(buffer); m_InfoArray[i].SetFilename(Temp.Left(len)); m_InfoArray[i].SetOffset(nOffset); } //Record the total size of the TOC for use //when extracting the data segment m_nTOCSize = LastOffset; } } //Close the archive Thisfile.Close(); return SUCCESS; } /******************************************************************************* * * Function: CSelfExtractor::AddFile * * Description: * Add a file to the archive * * Parameters: * CString File: Input File path * * Return: * BOOL: Success or Failure *******************************************************************************/ BOOL CSelfExtractor::AddFile(CString File) { if(m_nFiles == MAX_FILES) return FALSE; if(m_InfoArray[m_nFiles].SetData(File)) { m_nFiles++; return TRUE; } return FALSE; } /******************************************************************************* * * Function: CSelfExtractor::Reset * * Description: * Reset the CSEFileInfo Array * * Parameters: * None * * Return: * None *******************************************************************************/ void CSelfExtractor::Reset() { for(int i = 0; i < MAX_FILES; i++) m_InfoArray[i].Reset(); m_nFiles = 0; m_nTOCSize = 0; } /******************************************************************************* * * Function: CSelfExtractor::EnsureTrailingBackSlash * * Description: * Ensure that the string has a trailing backslash * * Parameters: * CString &string: Pathname * * Return: * CString: Pathname *******************************************************************************/ CString CSelfExtractor::EnsureTrailingBackSlash(CString &string) { int len = string.GetLength(); if(string[len - 1] != ‘\\‘) string += "\\"; return string; } /******************************************************************************* * * Function: CSelfExtractor::GetThisFileName * * Description: * Get this executable‘s file path * * Parameters: * None * * Return: * CString: Full Path for this executable *******************************************************************************/ CString CSelfExtractor::GetThisFileName() { char FullName[MAX_PATH+1]; GetModuleFileName(NULL,FullName,MAX_PATH); return CString(FullName); }
// ShellFileOp.cpp: implementation of the CShellFileOp class. // // Tim Johnson timj@progsoc.uts.edu.au // Written : July 1998 // // Copyright 1998 // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ShellFileOp.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// // // CShellFileOp () // // Basic constructor // CShellFileOp::CShellFileOp() { m_lMaxSrcCount = 0; m_lMaxDestCount = 0; m_lCurSrcCount = 0; m_lCurDestCount = 0; m_pSrc = NULL; m_pDest = NULL; m_pTo = NULL; m_pFrom = NULL; m_pTitle = NULL; m_FileOp.hwnd = NULL; m_FileOp.wFunc = 0; m_FileOp.pFrom = NULL; m_FileOp.pTo = NULL; m_FileOp.fFlags = 0; m_FileOp.fAnyOperationsAborted = FALSE; m_FileOp.hNameMappings = NULL; m_FileOp.lpszProgressTitle = NULL; } // // CShellFileOp // // Complex constructor - performs the operation straight away // CShellFileOp::CShellFileOp( const HWND phWnd, const UINT wFunc, const CString sFrom, const CString sTo, const FILEOP_FLAGS fFlags, const CString sProgressTitle) { m_lMaxSrcCount = 0; m_lMaxDestCount = 0; m_lCurSrcCount = 0; m_lCurDestCount = 0; m_pSrc = NULL; m_pDest = NULL; m_pTo = NULL; m_pFrom = NULL; m_pTitle = NULL; m_FileOp.hwnd = NULL; m_FileOp.wFunc = 0; m_FileOp.pFrom = NULL; m_FileOp.pTo = NULL; m_FileOp.fFlags = 0; m_FileOp.fAnyOperationsAborted = FALSE; m_FileOp.hNameMappings = NULL; m_FileOp.lpszProgressTitle = NULL; SetParent(phWnd); AddFile(SH_SRC_FILE, sFrom); AddFile(SH_DEST_FILE, sTo); SetFlags(fFlags); SetTitle(sProgressTitle); switch (wFunc) { case FO_COPY: CopyFiles(); break; case FO_DELETE: DeleteFiles(); break; case FO_MOVE: MoveFiles(); break; case FO_RENAME: RenameFiles(); break; default: break; } } // // ~CShellFileOp() // // deconstructor - kill all memory before object destruction // CShellFileOp::~CShellFileOp() { //free all malloc‘d blocks if (m_pTo) free ((void *)m_pTo ); if (m_pFrom) free ((void *)m_pFrom); if (m_pTitle) free ((void *)m_pTitle); } // // long CopyFiles ( ) // // Function to perform copy operation // long CShellFileOp::CopyFiles() { m_FileOp.fAnyOperationsAborted = FALSE; m_FileOp.wFunc = FO_COPY; return SHFileOperation(&m_FileOp); } // // long DeleteFiles ( ) // // Function to perform delete operation // long CShellFileOp::DeleteFiles() { m_FileOp.fAnyOperationsAborted = FALSE; m_FileOp.wFunc = FO_DELETE; return SHFileOperation(&m_FileOp); } // // long MoveFiles ( ) // // Function to perform move operation // long CShellFileOp::MoveFiles() { m_FileOp.fAnyOperationsAborted = FALSE; m_FileOp.wFunc = FO_MOVE; return SHFileOperation(&m_FileOp); } // // long RenameFiles ( ) // // Function to perform rename operation // long CShellFileOp::RenameFiles() { m_FileOp.fAnyOperationsAborted = FALSE; m_FileOp.wFunc = FO_RENAME; return SHFileOperation(&m_FileOp); } // // void ClearFiles ( const int iSrcDest ) // // Clears a list of files // void CShellFileOp::ClearFiles(const int iSrcDest) { if (iSrcDest == SH_SRC_FILE) { if (m_pFrom) { free ((void *)m_pFrom); m_pFrom = NULL; m_FileOp.pFrom = m_pFrom; m_lMaxSrcCount = 0; m_lCurSrcCount = 0; } } else { if (m_pTo) { free ((void *)m_pTo ); m_pTo = NULL; m_FileOp.pTo = m_pTo; m_lMaxDestCount = 0; m_lCurDestCount = 0; } } } // // void AddFile ( const int iSrcDest, CString sFile ) // // Adds another filename to the end of the current string // void CShellFileOp::AddFile(const int iSrcDest, const CString sFile) { int iLength = sFile.GetLength() + 1; //+1 for the null if (iSrcDest == SH_SRC_FILE) { //check enough allocated space... if ((m_lCurSrcCount + iLength + 1)> m_lMaxSrcCount) //+1 for the double null termination... { //have to get more mem. GrabMem(iSrcDest, (m_lCurSrcCount + iLength + 1)); } //now theres enough memory! yay. //now copy the filename in strcpy(m_pSrc, (LPCTSTR)sFile); //go to end of this files null term. m_pSrc += iLength; m_lCurSrcCount += iLength; //always keep it double null terminated, but don‘t // increment past it incase we want to add more files m_pSrc[0] = 0; } else { //check enough allocated space... if ((m_lCurDestCount + iLength + 1)> m_lMaxDestCount) //+1 for the double null termination... { //have to get more mem. GrabMem(iSrcDest, (m_lCurDestCount + iLength + 1)); } //now theres enough memory! yay. //now copy the filename in strcpy(m_pDest, (LPCTSTR)sFile); //go to end of this files null term. m_pDest += iLength; m_lCurDestCount += iLength; //always keep it double null terminated, but don‘t // increment past it incase we want to add more files m_pDest[0] = 0; } } // // SetMaxCount( const int iSrcDest, long lMax ) // // Function to pre-allocate string memory to prevent // lots of re-allocations // void CShellFileOp::SetMaxCount(const int iSrcDest, const long lMax) { if (iSrcDest == SH_SRC_FILE) { m_lMaxSrcCount = lMax + 1; //+1 for double null term. GrabMem(iSrcDest, m_lMaxSrcCount); } else { m_lMaxDestCount = lMax + 1; //+1 for double null term. GrabMem(iSrcDest, m_lMaxDestCount); } } // // SetTitle ( CString sTitle ) // // Function to set the dialog title from a string // void CShellFileOp::SetTitle(CString sTitle) { int iLength; char * pBuf; //free mem of current title if (m_pTitle) { free ((void *)m_pTitle); m_pTitle = NULL; m_FileOp.lpszProgressTitle = NULL; } iLength = sTitle.GetLength()+1; if (iLength > 1) { //grab more mem m_pTitle = (char *)malloc(iLength); //copy the title pBuf = sTitle.GetBuffer(iLength); strcpy(m_pTitle, pBuf); //now point the struct to the title m_FileOp.lpszProgressTitle = m_pTitle; } } // // SetTitle ( const int nTitle ) // // Function to set the dialog title from a resource identifier // void CShellFileOp::SetTitle( const int nTitle ) { CString sTitle; sTitle.LoadString(nTitle); SetTitle(sTitle); } // // SetParent ( const HWND phWnd ) // // Function to set the parent dialog // void CShellFileOp::SetParent(const HWND phWnd) { m_FileOp.hwnd = phWnd; } // // BOOL AnyOperationsAborted ( ) const // // Function to get Abort flag // BOOL CShellFileOp::AnyOperationsAborted() const { return m_FileOp.fAnyOperationsAborted; } // // FILEOP_FLAGS GetFlags() const // // Function to return the operation flags // FILEOP_FLAGS CShellFileOp::GetFlags() const { return m_FileOp.fFlags; } // // SetFlags ( const FILEOP_FLAGS fNewFlags ) // // Function to set the operation flags // void CShellFileOp::SetFlags(const FILEOP_FLAGS fNewFlags) { m_FileOp.fFlags = fNewFlags; } // // GrabMem( const int iSrcDest, const long lNum ) // // function to grab some string space memory // void CShellFileOp::GrabMem(const int iSrcDest, const long lNum) { char * pMem; long lOffset; //get current ptr if (iSrcDest == SH_SRC_FILE) { pMem = m_pFrom; } else { pMem = m_pTo; } if (pMem) //some mem is already allocated! { //have to make sure our offset ptrs dont get screwed up... if (iSrcDest == SH_SRC_FILE) { lOffset = (m_pSrc - pMem); } else { lOffset = (m_pDest - pMem); } //get more! pMem = (char *)realloc((void *)pMem, lNum); //reassign offset ptr, and max counts if (iSrcDest == SH_SRC_FILE) { m_pSrc = pMem + lOffset; m_lMaxSrcCount = lNum; } else { m_pDest = pMem + lOffset; m_lMaxDestCount = lNum; } } else { //get first block pMem = (char *)malloc(lNum); //assign offset ptr to start of block, and max counts if (iSrcDest == SH_SRC_FILE) { m_pSrc = pMem; m_lMaxSrcCount = lNum; } else { m_pDest = pMem; m_lMaxDestCount = lNum; } pMem[0] = 0; //ensure null terminated } //assign ptrs in sh structure. if (iSrcDest == SH_SRC_FILE) { m_pFrom = pMem; m_FileOp.pFrom = m_pFrom; } else { m_pTo = pMem; m_FileOp.pTo = m_pTo; } }
/************************************************************************************* * * File: SEFileInfo.h * Version: 1.0 * * Author: James Spibey * Date: 04/08/1999 * E-mail: spib@bigfoot.com * * Specification of the CSEFileInfo class * * You are free to use, distribute or modify this code * as long as this header is not removed or modified. * * This class holds data regarding each file in an archive * *************************************************************************************/ #if !defined(AFX_SEFILEINFO_H__5C3D775E_497B_11D3_A8BC_0050043A01C0__INCLUDED_) #define AFX_SEFILEINFO_H__5C3D775E_497B_11D3_A8BC_0050043A01C0__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 class CSEFileInfo { public: CSEFileInfo(); ~CSEFileInfo(); void Serialize(CArchive &ar); BOOL SetData(CString File); void SetFilename(CString file){m_strFilename = file;} void SetSize(int size){m_nSize = size;} void SetOffset(int offset){m_nOffset = offset;} CString GetPathname(){return m_strPathname;} CString GetFilename(){return m_strFilename;} int GetFileSize(){return m_nSize;} int GetFileOffset(){return m_nOffset;} void Reset(); protected: CString m_strFilename; //Name of file CString m_strPathname; //Path to file to add int m_nSize; //Size of file int m_nOffset; //Start Offset }; #endif // !defined(AFX_SEFILEINFO_H__5C3D775E_497B_11D3_A8BC_0050043A01C0__INCLUDED_)
/************************************************************************************* * * File: SelfExtracter.h * Version: 1.0 * * Author: James Spibey * E-mail: spib@bigfoot.com * * Specification of the CSelfExtracter class * * This code was based on suggestions from :- * Levente Farkas, Roger Allen, G黱ter (surname unknown) * * You are free to use, distribute or modify this code * as long as this header is not removed or modified. * * Self Extractor (SFX) File Format * --------------------------------- * * Starting from the end of the archive and working backwards :- * * Header Info * 10 bytes Signature - Identifier for SFX archive * 4 bytes Number of files in archive * * Table of Contents * * Contains one record in the following format for each file * 4 bytes Length of filename * variable Filename * 4 bytes Length of File * 4 bytes Offset in archive to data * * Data Segment * Each file is written (uncompressed) here in the order of the TOC * * After this is the extractor executable. * *************************************************************************************/ #if !defined(AFX_SELFEXTRACTOR_H__849C04B2_4988_11D3_A8BC_0050043A01C0__INCLUDED_) #define AFX_SELFEXTRACTOR_H__849C04B2_4988_11D3_A8BC_0050043A01C0__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 #include "SEFileInfo.h" #include "ShellFileOp.h" #define NO_SOURCE 1000 #define INVALID_SIG 1001 #define SUCCESS 1002 #define COPY_FAILED 1003 #define NOTHING_TO_DO 1004 #define OUTPUT_FILE_ERROR 1005 #define INPUT_FILE_ERROR 1006 #define RESOURCE_ERROR 1007 #define MAX_FILES 256 #define SIGNATURE "!LYME_SFX!" typedef void (* funcPtr)(void *, void*); class CSelfExtractor { public: CSelfExtractor(); virtual ~CSelfExtractor(); //Creation int Create(CString ExtractorPath, CString FilePath, funcPtr function = NULL, void * userData =http://www.mamicode.com/ NULL); int Create(UINT Resource, CString FilePath, funcPtr function = NULL, void * userData =http://www.mamicode.com/ NULL); bool GetResource(UINT Resource,CString &Filename ); BOOL AddFile(CString Filename); //Extraction int Extract(int index, CString Dir); int ExtractAll(CString dir, funcPtr function = NULL, void * userData =http://www.mamicode.com/ NULL); int ReadTOC(CString Filename); //Data retrieval inline int GetFileSize(int index){return m_InfoArray[index].GetFileSize();} inline int GetFileCount(){return m_nFiles;} CSEFileInfo GetItem(int item){return m_InfoArray[item];} //Helpers void Reset(); protected: //Helpers CString GetThisFileName(); CString EnsureTrailingBackSlash(CString &string); int CreateArchive(CFile* fp, funcPtr function, void* userData); int ExtractOne(CFile* fp, int index, CString Dir); //Data CString m_strWorkingDir; CSEFileInfo m_InfoArray[MAX_FILES]; //Array of file information int m_nFiles; //No of files in archive int m_nTOCSize; //Size of Table of contents }; #endif // !defined(AFX_SELFEXTRACTOR_H__849C04B2_4988_11D3_A8BC_0050043A01C0__INCLUDED_)
// ShellFileOp.h: interface for the CShellFileOp class. // // Tim Johnson timj@progsoc.uts.edu.au // Written : July 1998 // // Copyright 1998 // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_SHELLFILEOP_H__DA3A3661_1EF3_11D2_9E56_444553540000__INCLUDED_) #define AFX_SHELLFILEOP_H__DA3A3661_1EF3_11D2_9E56_444553540000__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 //constats for use in iSrcDest arguements const int SH_SRC_FILE = 0; const int SH_DEST_FILE = 1; class CShellFileOp { public: // //simple constructor // CShellFileOp(); // //complex constructor - performs the operation straight away // CShellFileOp( const HWND phWnd, const UINT wFunc, const CString sFrom, const CString sTo, const FILEOP_FLAGS fFlags, const CString sProgressTitle); // //destructor // virtual ~CShellFileOp(); public: //operations // // Function to perform copy operation // long CopyFiles(); // // Function to perform delete operation // long DeleteFiles(); // // Function to perform move operation // long MoveFiles(); // // Function to perform rename operation // long RenameFiles(); // // Adds another filename to the end of the current string // void AddFile(const int iSrcDest, const CString sFile); // // Clears a list of files // void ClearFiles(const int iSrcDest); // // Function to pre-allocate string memory to prevent // lots of re-allocations // void SetMaxCount(const int iSrcDest, const long lMax); // // Function to set the dialog title // sTitle is a string to be used // nTitle is a resource ID to get the string from void SetTitle(CString sTitle); void SetTitle(const int nTitle); // // Function to set the parent HWND of the dialog // void SetParent(const HWND phWnd); // // Function to get Abort flag // BOOL AnyOperationsAborted() const; // // Functions to get/set the operation flags // // Flags that control the file operation. This member can be a combination of the // following values: // // FOF_ALLOWUNDO Preserves undo information, if possible. // // FOF_CONFIRMMOUSE Not implemented. // // FOF_FILESONLY Performs the operation only on files if a wildcard // filename (*.*) is specified. // // FOF_MULTIDESTFILES Indicates that the pTo member specifies multiple destination // files (one for each source file) rather than one directory // where all source files are to be deposited. // // FOF_NOCONFIRMATION Responds with "yes to all" for any dialog box that is // displayed. // // FOF_NOCONFIRMMKDIR Does not confirm the creation of a new directory if the // operation requires one to be created. // // FOF_RENAMEONCOLLISION Gives the file being operated on a new name (such as // "Copy #1 of...") in a move, copy, or rename operation if a // file of the target name already exists. // // FOF_SILENT Does not display a progress dialog box. // // FOF_SIMPLEPROGRESS Displays a progress dialog box, but does not show the // filenames. FILEOP_FLAGS GetFlags() const; void SetFlags(const FILEOP_FLAGS fNewFlags); private: //operations // function to grab some string space memory void GrabMem(const int iSrcDest, const long lNum); private: //attributes //max no. char in source string long m_lMaxSrcCount; //max no. char in dest string long m_lMaxDestCount; //current no. char in source string long m_lCurSrcCount; //current no. char in dest string long m_lCurDestCount; //structure for shell call SHFILEOPSTRUCT m_FileOp; //pointer to start of source string char * m_pTo; //pointer to start of dest string char * m_pFrom; //current pointer in source string char * m_pSrc; //current pointer in dest string char * m_pDest; //title to be used on dialog char * m_pTitle; }; #endif // !defined(AFX_SHELLFILEOP_H__DA3A3661_1EF3_11D2_9E56_444553540000__INCLUDED_)
10、压缩解压,引用别人的
///////////////////////////////////////////////////////////////////////////// // 文件名: <ZipImplement.h> // 创建者: <hwfly> // 创建日期: 2009-09-27 下午 04:51:46 // // 说明:压缩解压缩地图文件夹 ///////////////////////////////////////////////////////////////////////////// #pragma once #include "zip.h" #include "unzip.h" class CZipImplement { public: CZipImplement(void); ~CZipImplement(void); private: HZIP hz; //Zip文件句柄 ZRESULT zr; //操作返回值 ZIPENTRY ze; //Zip文件入口 CString m_FolderPath; //folder路径 CString m_FolderName; //folder将要被压缩的文件夹名 private: //实现遍历文件夹 void BrowseFile(CString &strFile); //获取相对路径 void GetRelativePath(CString& pFullPath, CString& pSubString); //创建路径 BOOL CreatedMultipleDirectory(char* direct); ///* //*********************************************************************** //* 函数: TransCStringToTCHAR //* 描述:将CString 转换为 TCHAR* //*********************************************************************** //*/ //TCHAR* CString2TCHAR(CString &str) //{ // int iLen = str.GetLength(); // TCHAR* szRs = new TCHAR[iLen]; // lstrcpy(szRs, str.GetBuffer(iLen)); // str.ReleaseBuffer(); // return szRs; //} public: //压缩文件夹接口 BOOL Zip_PackFiles(CString& pFilePath, CString& mZipFileFullPath); //解压缩文件夹接口 BOOL Zip_UnPackFiles(CString &mZipFileFullPath, CString& mUnPackPath); public: //静态方法提供文件夹路径检查 static BOOL FolderExist(CString& strPath); };
///////////////////////////////////////////////////////////////////////////// // 文件名: <ZipImplement.cpp> // 创建者: <hwfly> // 创建日期: 2009-09-27 下午 04:51:46 // // 说明:压缩解压缩地图文件夹 ///////////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include "zipimplement.h" #include <direct.h> #include <vector> #include <xstring> CZipImplement::CZipImplement(void) { } CZipImplement::~CZipImplement(void) { } ///////////////////////////////////////////////////////////////////////////// // 函数说明: 实现压缩文件夹操作 // 参数说明: [in]: pFilePath 要被压缩的文件夹 // mZipFileFullPath 压缩后的文件名和路径 // 返回值: 参数有误的情况下返回FALSE,压缩成功后返回TRUE // 函数作者: <hwfly> // 创建日期: 2009-09-27 下午 04:58:52 ///////////////////////////////////////////////////////////////////////////// BOOL CZipImplement::Zip_PackFiles(CString& pFilePath, CString& mZipFileFullPath) { //参数错误 if ((pFilePath == L"") || (mZipFileFullPath == L"")) { //路径异常返回 return FALSE ; } if(!CZipImplement::FolderExist(pFilePath)) { //要被压缩的文件夹不存在 return FALSE ; } CString tZipFilePath = mZipFileFullPath.Left(mZipFileFullPath.ReverseFind(‘/‘) + 1); if(!CZipImplement::FolderExist(tZipFilePath)) { //ZIP文件存放的文件夹不存在创建它 char* temp=tZipFilePath.GetBuffer(tZipFilePath.GetLength()); if (FALSE == CreatedMultipleDirectory(temp)) { //创建目录失败 return FALSE; } } //获得文件夹的名字 if(pFilePath.Right(1) == L"/") { this->m_FolderPath = pFilePath.Left(pFilePath.GetLength() - 1); m_FolderName = m_FolderPath.Right(m_FolderPath.GetLength() - m_FolderPath.ReverseFind(‘/‘) - 1); } else { this->m_FolderPath = pFilePath; m_FolderName = pFilePath.Right(pFilePath.GetLength() - pFilePath.ReverseFind(‘/‘) - 1); } /************************************************************************/ //创建ZIP文件 hz=CreateZip(mZipFileFullPath,0); if(hz == 0) { //创建Zip文件失败 return FALSE; } //递归文件夹,将获取的问价加入ZIP文件 BrowseFile(pFilePath); //关闭ZIP文件 CloseZip(hz); /************************************************************************/ CFileFind tFFind; if (!tFFind.FindFile(mZipFileFullPath)) { //压缩失败(未发现压缩后的文件) return FALSE; } return TRUE; } ///////////////////////////////////////////////////////////////////////////// // 函数说明: 解压缩文件夹 // 参数说明: [in]: mUnPackPath 解压后文件存放的路径 // mZipFileFullPath ZIP文件的路径 // 返回值: // 函数作者: <hwfly> // 创建日期: 2009-09-27 上午 11:04:28 ///////////////////////////////////////////////////////////////////////////// BOOL CZipImplement::Zip_UnPackFiles(CString &mZipFileFullPath, CString& mUnPackPath) { //参数错误 if ((mUnPackPath == L"") || (mZipFileFullPath == L"")) { //路径异常返回 return FALSE ; } CFileFind tFFind; if (!tFFind.FindFile(mZipFileFullPath)) { //压缩失败(未发现压缩文件) return FALSE; } //如果解压缩的路径不存在 试图创建它 CString tZipFilePath = mUnPackPath; if(!CZipImplement::FolderExist(tZipFilePath)) { //解压后存放的文件夹不存在 创建它 char* temp=tZipFilePath.GetBuffer(tZipFilePath.GetLength()); if (FALSE == CreatedMultipleDirectory(temp)) { //创建目录失败 return FALSE; } } /************************************************************************/ //打开ZIP文件 hz=OpenZip(mZipFileFullPath,0); if(hz == 0) { //打开Zip文件失败 return FALSE; } zr=SetUnzipBaseDir(hz,mUnPackPath); if(zr != ZR_OK) { //打开Zip文件失败 CloseZip(hz); return FALSE; } zr=GetZipItem(hz,-1,&ze); if(zr != ZR_OK) { //获取Zip文件内容失败 CloseZip(hz); return FALSE; } int numitems=ze.index; for (int i=0; i<numitems; i++) { zr=GetZipItem(hz,i,&ze); zr=UnzipItem(hz,i,ze.name); if(zr != ZR_OK) { //获取Zip文件内容失败 CloseZip(hz); return FALSE; } } CloseZip(hz); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // 函数说明: 检查指定的文件夹是否存在 // 参数说明: [in]:strPath 检查的文件夹 (此方法会主动向路径末尾添加*.*) // 返回值:BOOL类型,存在返回TRUE,否则为FALSE // 函数作者: <hwfly> // 创建日期: 2009-09-27 下午 02:16:36 ///////////////////////////////////////////////////////////////////////////// BOOL CZipImplement::FolderExist(CString& strPath) { CString sCheckPath = strPath; if(sCheckPath.Right(1) != L"\\") { sCheckPath += L"\\"; } sCheckPath += L"*.*"; WIN32_FIND_DATA wfd; BOOL rValue = FALSE; HANDLE hFind = FindFirstFile(sCheckPath, &wfd); if ((hFind!=INVALID_HANDLE_VALUE) && (wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) || (wfd.dwFileAttributes&FILE_ATTRIBUTE_ARCHIVE)) { //如果存在并类型是文件夹 rValue =http://www.mamicode.com/ TRUE; } FindClose(hFind); return rValue; } ///////////////////////////////////////////////////////////////////////////// // 函数说明: 遍历文件夹 // 参数说明: [in]:strFile 遍历的文件夹(此方法会主动向路径末尾添加*.*) // 返回值:BOOL类型,存在返回TRUE,否则为FALSE // 函数作者: <hwfly> // 创建日期: 2009-09-27 下午 02:16:36 ///////////////////////////////////////////////////////////////////////////// void CZipImplement::BrowseFile(CString &strFile) { CFileFind ff; CString szDir = strFile; if(szDir.Right(1) != L"\\") szDir += L"\\"; szDir += L"*.*"; BOOL res = ff.FindFile(szDir); while(res) { res = ff.FindNextFile(); if(ff.IsDirectory() && !ff.IsDots()) { //如果是一个子目录,用递归继续往深一层找 CString strPath = ff.GetFilePath(); CString subPath; GetRelativePath(strPath,subPath); //将文件添加到ZIP文件 ZipAddFolder(hz,subPath); BrowseFile(strPath); } else if(!ff.IsDirectory() && !ff.IsDots()) { //显示当前访问的文件(完整路径) CString strPath = ff.GetFilePath(); CString subPath; GetRelativePath(strPath,subPath); //将文件添加到ZIP文件 ZipAdd(hz,subPath,strPath); } } //关闭 ff.Close(); } ///////////////////////////////////////////////////////////////////////////// // 函数说明: 获取相对路径 // 参数说明: [in]:pFullPath 当前文件的完整路径 [out] : 解析后的相对路径 // 函数作者: <hwfly> // 创建日期: 2009-9-28 上午 11:17:21 ///////////////////////////////////////////////////////////////////////////// void CZipImplement::GetRelativePath(CString& pFullPath,CString& pSubString) { pSubString = pFullPath.Right(pFullPath.GetLength() - this->m_FolderPath.GetLength() + this->m_FolderName.GetLength()); } ///////////////////////////////////////////////////////////////////////////// // 函数说明: 创建多级目录 // 参数说明: [in]: 路径字符串 // 返回值: BOOL 成功True 失败False // 函数作者: <hwfly> // 创建日期: 2009-9-28 下午 04:53:20 ///////////////////////////////////////////////////////////////////////////// BOOL CZipImplement::CreatedMultipleDirectory(char* direct) { std::string Directoryname = direct; if (Directoryname[Directoryname.length() - 1] != ‘\\‘) { Directoryname.append(1, ‘\\‘); } std::vector< std::string> vpath; std::string strtemp; BOOL bSuccess = FALSE; for (int i = 0; i < Directoryname.length(); i++) { if ( Directoryname[i] != ‘\\‘) { strtemp.append(1,Directoryname[i]); } else { vpath.push_back(strtemp); strtemp.append(1, ‘\\‘); } } std::vector<std::string>:: const_iterator vIter; for (vIter = vpath.begin();vIter != vpath.end(); vIter++) { bSuccess = CreateDirectory(vIter->c_str(), NULL) ? TRUE :FALSE; } return bSuccess; }
11、添加资源到工程中
以添加Resource.zip 为例
1、把Resource.zip添加到文件夹res替换原来的压缩文件。
2、在资源视图中右键-》添加资源 -》自定义-》资源类型-》导入 资源
安装包设计-------打包(MFC)---------知识总结