安装包设计-------打包(MFC)---------知识总结

Posted 卡贝天师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安装包设计-------打包(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;      

}
View Code

 

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;

}
View Code

 

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;

}
View Code

 

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;

}
View Code

 

8、从当前的应用程序中抽取资源

bool GetResourceFromLocal(CString &DesPath)
{   

    //从本地应用获得资源文件.zip
    CString tempPathPro = DesPath + "/" + "Resource.zip"; //输出路径
    HRSRC hrSrc = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_AFX_RESOURCE), "AFX_RESOURCE");
    if(hrSrc == 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;
}
View Code

 

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 = "";
}
View Code

 

/*************************************************************************************
*
*    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 = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(resource), "AFX_EXE");
    if(hrSrc == 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 = FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(resource), "AFX_EXE");
    if(hrSrc == NULL)
        return RESOURCE_ERROR;

    HGLOBAL hGlobal = LoadResource(AfxGetResourceHandle(), hrSrc);
    if(hGlobal == NULL)
        return RESOURCE_ERROR;

    LPVOID lpExe = LockResource(hGlobal);
    if(lpExe == NULL)
        return RESOURCE_ERROR;
        */
    //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] != \'Advanced Installer 打包后,安装包在WIN10下重启后再次运行安装的解决办法

electron打包桌面应用程序打包成安装包安装包,怎么打包

winform项目打包后生成一个exe安装包

各种安装包打包发布工具

各种安装包打包发布工具

Python如何打包EXE可执行文件