实现程序合并和分解

原创 2016年08月29日 00:10:36

1.前言

公司需要实现我们的程序和客户的程序合并成一个,且要先运行我们的,客户的才能正确运行。所以需要做一个简单的类似于安装包一样的东东。

2.解决

有很多方法,这里提供两种:

2.1 可以将客户的程序作为我们程序的一个资源来实现合并和释放

合并代码片段

void merge()
{
    HANDLE hUpdateRes; 
    hUpdateRes = BeginUpdateResource(strDesPath.c_str(), FALSE);
    if (hUpdateRes != NULL)
    {
        HANDLE hOpenFile = (HANDLE)CreateFile(wstrloginpath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
        if (hOpenFile != INVALID_HANDLE_VALUE)
        {
            DWORD fileSize = GetFileSize(hOpenFile, NULL);
            char *pBuffer = (char *) malloc(fileSize + 1);     //这里可能会失败
            DWORD RSize = 0;
            ReadFile(hOpenFile, pBuffer, fileSize, &RSize, NULL);

            BOOL result = UpdateResource(hUpdateRes,   
                TEXT("FILE"),                        
                TEXT("ALACLIENT"),       
                MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
                (char *)pBuffer,                        
                fileSize);  //fileSize + 5
            if (!result)
                writelog("failed UpdateResource exe in generatefunc");

            CloseHandle(hOpenFile);
            free(pBuffer);
        }
        EndUpdateResource(hUpdateRes, FALSE);
    }
}

分解代码片段

void splite()
{
    HRSRC hrSrc;
    HGLOBAL hGlobal;
    LPVOID lpExe;
    DWORD dwSize;
    HANDLE hFile;

    hrSrc = FindResource(NULL, TEXT("ALACLIENT"), TEXT("FILE"));
    hGlobal = LoadResource(NULL, hrSrc);
    lpExe = LockResource(hGlobal);
    dwSize = SizeofResource(NULL, hrSrc);
    hFile = CreateFile(
        strLoginPath.c_str(),
        GENERIC_ALL,
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if(hFile != INVALID_HANDLE_VALUE)
    {
        DWORD dwBytesWritten = 0;
        if(WriteFile(hFile,lpExe, dwSize, &dwBytesWritten,NULL)==FALSE)
        {
            //这里进行下解密
        }
        CloseHandle(hFile);
    }
    UnlockResource(hGlobal);
    FreeResource(hGlobal);
}

2.2 可以将客户的程序合并到我们的程序后面

合并部分代码片段

void merge()
{
    DWORD dwSrcLen = 0;
    HANDLE hAppend = CreateFile(strDesPath.c_str(),  // open Two.txt
        FILE_APPEND_DATA,         // open for writing
        FILE_SHARE_READ,          // allow multiple readers
        NULL,                     // no security
        OPEN_ALWAYS,              // open or create
        FILE_ATTRIBUTE_NORMAL,    // normal file
        NULL);                    // no attr. template

    if (hAppend == INVALID_HANDLE_VALUE)
    {
        //printf("Could not open Two.txt.");
        writelog("failed open despath.");
        MessageBox(NULL, TEXT("生成失败,请重新封装"), TEXT("提示"), 0);
        CloseHandle(hAppend);
        hAppend = INVALID_HANDLE_VALUE;
        return;
    }
    else
        dwSrcLen = GetFileSize(hAppend, NULL);


    HANDLE hFileZip = CreateFile(wstrZipPath.c_str(),  // open One.txt
        GENERIC_READ,             // open for reading
        0,                        // do not share
        NULL,                     // no security
        OPEN_EXISTING,            // existing file only
        FILE_ATTRIBUTE_NORMAL,    // normal file
        NULL);                    // no attr. template

    if (hFileZip != INVALID_HANDLE_VALUE)
    {
        DWORD dwBytesRead = sizeof(DWORD), dwBytesWritten = 0;
        DWORD dwFileLen = GetFileSize(hFileZip, NULL);
        DWORD dwPos = SetFilePointer(hAppend, 0, NULL, FILE_END);
        BYTE   buff[4096] = {0};

        LockFile(hAppend, dwPos, 0, dwBytesRead, 0);
        WriteFile(hAppend, &dwFileLen, sizeof(DWORD), &dwBytesWritten, NULL);
        UnlockFile(hAppend, dwPos, 0, dwBytesRead, 0);

        while (ReadFile(hFileZip, buff, sizeof(buff), &dwBytesRead, NULL)
            && dwBytesRead > 0)
        {
            dwPos = SetFilePointer(hAppend, 0, NULL, FILE_END);
            LockFile(hAppend, dwPos, 0, dwBytesRead, 0);
            WriteFile(hAppend, buff, dwBytesRead, &dwBytesWritten, NULL);
            UnlockFile(hAppend, dwPos, 0, dwBytesRead, 0);
        }
        CloseHandle(hFileZip);
        hFileZip = INVALID_HANDLE_VALUE;


        dwPos = SetFilePointer(hAppend, 0, NULL, FILE_END);
        dwBytesRead = sizeof(DWORD);
        LockFile(hAppend, dwPos, 0, dwBytesRead, 0);
        WriteFile(hAppend, &dwSrcLen, sizeof(DWORD), &dwBytesWritten, NULL);
        UnlockFile(hAppend, dwPos, 0, dwBytesRead, 0);
    }
    else
    {
        MessageBox(NULL, TEXT("生成失败,请重新进行生成."), TEXT("提示"), 0);
        CloseHandle(hAppend);
        hAppend = INVALID_HANDLE_VALUE;
        return;
    }
    CloseHandle(hAppend);
    hAppend = INVALID_HANDLE_VALUE;
}

分解部分代码片段

void splite()
{
    hFile = CreateFile(ptExePath, // open One.txt
        GENERIC_READ,             // open for reading
        0,                        // do not share
        NULL,                     // no security
        OPEN_EXISTING,            // existing file only
        FILE_ATTRIBUTE_NORMAL,    // normal file
        NULL);                    // no attr. template
    if (hFile == INVALID_HANDLE_VALUE)
        break;
    SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
    dwFileLen = GetFileSize(hFile, NULL);

    //LONG lPos = -sizeof(DWORD);
    dwPos = SetFilePointer(hFile, -sizeof(DWORD), NULL, FILE_END);
    ReadFile(hFile, &snAlaPackLen, sizeof(DWORD), &dwBytesRead, NULL);

    //这里进行对数据提取cloud文件.
    if (snAlaPackLen < 100 || snAlaPackLen > dwFileLen)
        break;

    SetFilePointer(hFile, snAlaPackLen, NULL, FILE_BEGIN);
    if (snAlaPackLen + sizeof(DWORD) > dwFileLen)
        break;

    DWORD dwCloud = 0;
    ReadFile(hFile, &dwCloud, sizeof(DWORD), &dwBytesRead, NULL);
    if (snAlaPackLen + sizeof(DWORD) + dwCloud > dwFileLen)
        break;

    DWORD dwCount = dwCloud / sizeof(buff);
    DWORD dwValue = dwCloud % sizeof(buff);
    hFileZip = CreateFile(wstrTempZipPath.c_str(), // open Two.txt
        FILE_APPEND_DATA,         // open for writing
        FILE_SHARE_READ,          // allow multiple readers
        NULL,                     // no security
        OPEN_ALWAYS,              // open or create
        FILE_ATTRIBUTE_NORMAL,    // normal file
        NULL);                    // no attr. template
    if (hFileZip == INVALID_HANDLE_VALUE)
        break;

    for (DWORD dwIndex = 0; dwIndex < dwCount; ++dwIndex)
    {
        if (ReadFile(hFile, buff, sizeof(buff), &dwBytesRead, NULL) && dwBytesRead > 0)
        {
            dwPos = SetFilePointer(hFileZip, 0, NULL, FILE_END);
            LockFile(hFileZip, dwPos, 0, dwBytesRead, 0);
            WriteFile(hFileZip, buff, dwBytesRead, &dwBytesWritten, NULL);
            UnlockFile(hFileZip, dwPos, 0, dwBytesRead, 0);
        }
    }
    if (dwValue > 0)
    {
        if (ReadFile(hFile, buff, dwValue, &dwBytesRead, NULL) && dwBytesRead > 0)
        {
            dwPos = SetFilePointer(hFileZip, 0, NULL, FILE_END);
            LockFile(hFileZip, dwPos, 0, dwBytesRead, 0);
            WriteFile(hFileZip, buff, dwBytesRead, &dwBytesWritten, NULL);
            UnlockFile(hFileZip, dwPos, 0, dwBytesRead, 0);
        }
    }
    CloseHandle(hFileZip);
    hFileZip = INVALID_HANDLE_VALUE;
    CloseHandle(hFile);
    hFile = INVALID_HANDLE_VALUE;
}

3.备注

这里解释下第二种方法,因为无法将程序大小添加到文件头部,故将其添加到程序的尾部

相关文章推荐

Java文件拆分与合并

思路:用字节流把文件拆分,然后用序列流合并字节流。 练习:文件切割与合并 实现对大文件的切割与合并。按指定个数切(如把一个文件切成10份)或按指定大小切(如每份最大不超过10M),这两种方式都...

标识符和关键字与保留字

1.标识符程序员对程序中的各个元素加以命名时,使用的命名记号称为标识符。Java语言中,标识符是以字母、下划线( _ )、美元符( $ ) 开始的一个字符序列,后面可以跟字母、下划线、美元符、数字。2...

C++实现的大整数分解Pollard's rho算法程序

代码来自GeeksforGeeks的Pollard’s Rho Algorithm for Prime Factorization。 C++语言程序代码如下: /* C++ program to f...

微服务分解应用程序以实现可部署性与可扩展性(上)

在这篇文章中,你将了解使用微服务架构的动机以及它与更传统的巨石架构的不同之处。讨论微服务的优点和缺点,你将了解如何解决运用微服务架构包括内部服务通讯和分布式数据管理时遇到的一些关键性技术难题。...
  • saaspad
  • saaspad
  • 2016年11月08日 10:52
  • 535

微服务分解应用程序以实现可部署性与可扩展性(下)

在上篇 微服务分解应用程序以实现可部署性与可扩展性(上) 中了解了为什么要将应用程序分解为服务以及微服务架构的优缺点,接着我们来看一下在微服务架构中内部服务通讯和分布式数据管理时遇到的一些关键性技术难...
  • saaspad
  • saaspad
  • 2016年11月09日 10:43
  • 489

Linux下合并前缀相同的文件的程序流程及其C代码实现

一、概述 在实际的软件开发项目中,会出现对多个前缀(或后缀)相同的文件进行合并的需求。也就是说,将这些前缀(或后缀)相同的文件中的内容合并到一个文件中。这些文件的来源可能是前一流程中程序生成的文件,...
  • zhouzxi
  • zhouzxi
  • 2015年07月09日 10:57
  • 4947

C# Winform实现MDI程序子窗体与主窗体菜单合并

这里只讲在MDI中,子菜单与父菜单合并的简单方法。   首先在MDI的主窗体中: 1.  在主窗体构造函数中,添加如下代码,注意要在InitializeComponent调用之后,如:   ...
  • zjg528
  • zjg528
  • 2013年04月30日 19:57
  • 666

分治:合并排序的java程序实现

合并排序: 采用分治策略将待排序的元素分成大小大致相同的两个子集合,先对两个子集合进行排序,将排序好的子集合合并成排好序的集合。 其算法是复杂度T(n)=O(nlogn) 合并排序主要中主要是在...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:实现程序合并和分解
举报原因:
原因补充:

(最多只允许输入30个字)