精华内容
下载资源
问答
  • 多个文件合并成一个最终可执行文件,运行这个最终合成文件后,就相当于运行了合并前的多个文件。这种程序在木马程序合并中会经常用到,你想知道它是怎么用程序实现的么? 基本构成思想:其实,其中的构成思想非常...

       将多个文件合并成一个最终可执行文件,运行这个最终合成文件后,就相当于运行了合并前的多个文件。这种程序在木马程序合并中会经常用到,你想知道它是怎么用程序实现的么? 

      基本构成思想:其实,其中的构成思想非常简单。合并文件时:建立一个新的二进制文件,先写入你的自身捆绑程序的数据和其文件长度,再写入你要捆绑的第一个文件的数据和其文件长度,后再直接写入你要捆绑的第二个文件的数据和文件长度……,最后可直接写入你要捆绑的最后一个文件的数据(不需其文件长度)。分解释放最终合成文件时,也就是将上面的方法思想倒过来既可:打开最终合成文件,读取源自身捆绑程序文件长度,将文件指针移到自身捆绑程序数据后,读取第一个被绑定文件的长度,接着读取其长度的文件数据并写入到一新建文件1中,再读取第二个被绑定文件的长度,接着读取其长度的数据并写入到新建文件2中……,直到最后直接读取最后一个被绑定文件的数据并将其写入到最后一个新建文件中既可(下面实例仅告诉你如何实现二个文件的捆绑,至于多个文件的捆绑,读者只需略加改动)。 

      下面我来讲讲文件捆绑最核心的部分,以及如何具体将其用代码来实现的方法: 

      1、捆绑多个文件为一个可执行程序 

      先得到自身捆绑程序的文件长度和第一个要捆绑文件的文件长度,枚举第一个要捆绑文件有无图标,有的话就用它做为最终生成文件的图标,否则用自身捆绑程序所带默认图标做最终生成文件的图标。在新建二进制文件中写入自身捆绑程序的数据和其文件长度,再写入第一个要捆绑文件的数据及其文件长度,最后直接写入第二个文件的数据既可。 

      合并程序涵数的具体代码实现如下: 

      1   //定义要使用到的捆绑程序自身文件信息的结构体 
    2
    3   struct MODIFY_DATA {
    4
    5   unsigned int finder; // 常量(定位自身)
    6
    7   _off_t my_length; //文件长度(自身)
    8
    9   } modify_data = {0x12345678, 0};
    10
    11   //绑定二个文件为一个可执行文件
    12
    13   bool CBindFileDlg::Bind_Files()
    14
    15   {
    16
    17   FILE* myself; //自身文件
    18
    19   FILE* out; //最终合成文件
    20
    21   FILE* in; //待绑定文件
    22
    23   int bytesin; //一次读文件字节数
    24
    25   int totalbytes = 0; //读出文件总字节数
    26
    27   struct _stat ST; //文件的状态信息(如文件长度等)
    28
    29   unsigned int finder = 0x12345678; //自身文件定位
    30
    31   unsigned int i, k;
    32
    33   int l=1; //进度条状态显示变量
    34
    35   char buff[20]; //进度条状态显示变量
    36
    37   his_name = strFirstFilePath; //第一个绑定的文件名
    38
    39   _stat(my_name, &ST); //获取自身捆绑文件信息
    40
    41   modify_data.my_length = ST.st_size; //得到自身文件长度
    42
    43   if (modify_data.my_length == 0)
    44
    45   {
    46
    47   MessageBox("绑定文件中,自身文件长度为零时出错!","错误");
    48
    49   return false;
    50
    51   }
    52
    53   buf = (BYTE *)malloc(modify_data.my_length); //分配一定大小缓冲区
    54
    55   if (buf == NULL)
    56
    57   {
    58
    59   MessageBox("绑定文件中,分配自身文件长度时出错!","错误");
    60
    61   return false;
    62
    63   }
    64
    65   myself = fopen(my_name, "rb"); //打开自身文件
    66
    67   if (myself == NULL)
    68
    69   {
    70
    71   free(buf);
    72
    73   MessageBox("绑定文件中,打开自身文件时出错!","错误");
    74
    75   return false;
    76
    77   }
    78
    79   //先读取捆绑程序自身文件数据
    80
    81   bytesin = fread(buf, 1, modify_data.my_length, myself);
    82
    83   fclose(myself);
    84
    85   if (bytesin != modify_data.my_length)
    86
    87   {
    88
    89   free(buf);
    90
    91   MessageBox("绑定文件中,不能完全读取自身文件内容时出错!","错误");
    92
    93   return false;
    94
    95   }
    96
    97   //存储自身文件信息到缓冲区(如长度)
    98
    99   for (i = 0; i < modify_data.my_length - sizeof(finder); i += sizeof(finder))
    100
    101   {
    102
    103   for (k = 0; k < sizeof(finder); k++)
    104
    105   {
    106
    107   if (buf[i+k] != ((BYTE*)&finder)[k])
    108
    109   break; } if (k == sizeof(finder)) //定位并保存自身数据文件信息
    110
    111   {
    112
    113   memcpy(buf+ i, &modify_data, sizeof(modify_data));
    114
    115   break;
    116
    117   }
    118
    119   }
    120
    121   if (i >= modify_data.my_length - sizeof(finder))
    122
    123   {
    124
    125   free(buf);
    126
    127   MessageBox("绑定文件中,不能定位自身文件时出错!","错误");
    128
    129   return false;
    130
    131   }
    132
    133   //获取第一个要绑定文件的信息(文件长度)
    134
    135   if (_stat(strFirstFilePath, &ST) != 0 || ST.st_size == 0)
    136
    137   {
    138
    139   free(buf);
    140
    141   MessageBox("绑定文件中,读取第一个要绑定文件时出错!","错误");
    142
    143   return false;
    144
    145   }
    146
    147   //获取自身文件图标及第一个要绑定文件的图标(如第一个要绑定文件没有图标,
    148
    149   //则用自身文件图标。其涵数实现请参看例程)
    150
    151   list_my_icons();
    152
    153   out = fopen(strFinalFilePath, "wb"); //创建最终合成文件
    154
    155   if (out == NULL)
    156
    157   {
    158
    159   free(buf);
    160
    161   MessageBox("绑定文件中,创建绑定后生成的合成文件时出错!","错误");
    162
    163   return false;
    164
    165   }
    166
    167   //先将前面读出的自身捆绑程序的数据写入最终合成文件中
    168
    169   totalbytes += fwrite(buf, 1, bytesin, out);
    170
    171   in = fopen(strFirstFilePath, "rb"); //打开第一个要绑定的文件
    172
    173   if (in == NULL)
    174
    175   {
    176
    177   free(buf);
    178
    179   MessageBox("绑定文件中,打开第一个要绑定文件时出错!","错误");
    180
    181   return false;
    182
    183   }
    184
    185   //写入第一个要绑定文件的长度到最终合成文件中
    186
    187   totalbytes += fwrite(&ST.st_size, 1, sizeof(ST.st_size), out);
    188
    189   //写入最终分解后文件执行方式的标志位(同步或异步执行)
    190
    191   UpdateData(TRUE); //传控件值到变量m_Sync中
    192
    193   totalbytes += fwrite(&m_Sync, 1, sizeof(int), out);
    194
    195   //写入第一个要绑定文件的数据到最终合成文件中
    196
    197   while (bytesin = fread(buf, 1, modify_data.my_length, in))
    198
    199   {
    200
    201   totalbytes += fwrite(buf, 1, bytesin, out);
    202
    203   }
    204
    205   fclose(in); //关闭第一个绑定文件句柄
    206
    207   //设置进度条显示
    208
    209   m_Progress.SetRange(0,500);
    210
    211   for (int m = 0; m < 500; m++)
    212
    213   m_Progress.SetPos(m);
    214
    215   m_Parts = _ltoa(l, buff, 10);
    216
    217   m_Parts += _T("个文件已绑定");
    218
    219   UpdateData(FALSE);
    220
    221   l++;
    222
    223   in = fopen(strSecondFilePath, "rb"); //打开第二个要绑定的文件
    224
    225   if (in == NULL)
    226
    227   {
    228
    229   free(buf); MessageBox("绑定文件中,打开第二个要绑定文件时出错!","错误");
    230
    231   return false;
    232
    233   }
    234
    235   //直接写入第二个要绑定文件的数据到最终合成文件中
    236
    237   while (bytesin = fread(buf, 1, modify_data.my_length, in))
    238
    239   {
    240
    241   totalbytes += fwrite(buf, 1, bytesin, out);
    242
    243   }
    244
    245   //设置进度条显示
    246
    247   m_Progress.SetRange(0,500);
    248
    249   for (int n = 0; n < 500; n++)
    250
    251   m_Progress.SetPos(n);
    252
    253   m_Parts = _ltoa(l, buff, 10);
    254
    255   m_Parts += _T("个文件已绑定");
    256
    257   UpdateData(FALSE);
    258
    259   l++;
    260
    261   fclose(in); //关闭第二个绑定文件句柄
    262
    263   fclose(out); //关闭最终合成文件句柄
    264
    265   free(buf); //释放缓冲区
    266
    267   return true;
    268
    269   }


      2、 释放最终合成文件并同时运行它们。 

      打开自身文件,从中得到自身捆绑程序的文件长度,便可将文件指针定位到第一个被捆绑文件的位置,读取其文件长度和其数据,将其读出数据写入第一个新建文件中。同样,通过已读取的自身捆绑程序文件长度和第一个被捆绑文件的文件长度加上其保存这两个文件长度值的字节数,既可准确定位第二个被捆绑文件的位置,读取其数据,写入到第二个新建文件中。同时,运行这两个文件,最后再删除这两个文件既可。 

      l 释放最终合成文件的代码具体实现如下: 

      1   //创建分解文件后,运行各分解文件时的进程 
    2
    3   void CBindFileDlg::Create_Process(const char* temp_exe, BOOL async)
    4
    5   {
    6
    7   HANDLE hProcess; //进程句柄
    8
    9   HANDLE hThread; //线程句柄
    10
    11   PROCESS_INFORMATION PI; //进程信息
    12
    13   STARTUPINFO SI; //启动信息
    14
    15   memset(&SI, 0, sizeof(SI)); //分配一定的内存
    16
    17   SI.cb = sizeof(SI); //大小赋给启动信息内CB
    18
    19   CreateProcess(temp_exe, NULL, NULL, NULL, FALSE,NORMAL_PRIORITY_CLASS, NULL, NULL, &SI, &PI);
    20
    21   hProcess = PI.hProcess;
    22
    23   hThread = PI.hThread;
    24
    25   //异步执行时,执行后不删除分解后的文件;同步执行时,执行后删除分解后的文件
    26
    27   if (!async) //当同步执行时
    28
    29   {
    30
    31   //一直等待,直到当前程序运行进程结束
    32
    33   WaitForSingleObject(hProcess, INFINITE);
    34
    35   unlink(temp_exe); //删除temp.exe文件
    36
    37   }
    38
    39   }
    40
    41   //分解已合并的文件,同时运行它们
    42
    43   void CBindFileDlg::Unbind()
    44
    45   {
    46
    47   FILE* myself; //自身文件
    48
    49   FILE* out; //分解后文件
    50
    51   int bytesin; //一次读出文件的字节数
    52
    53   int totalbytes = 0; //读出文件的总字节数
    54
    55   char temp_exe1[] = "temp1.exe"; //分解后的绑定文件名一(可任意取)
    56
    57   char temp_exe2[] = "temp2.exe"; //分解后的绑定文件名二(可任意取)
    58
    59   int SyncFlag; //文件最终执行标志(同步或异步)
    60
    61   //先分配一定大小的缓冲区(大小等于捆绑程序长度)
    62
    63   buf = (BYTE*)malloc(modify_data.my_length);
    64
    65   myself = fopen(my_name, "rb"); //打开最终合成文件
    66
    67   if (myself == NULL)
    68
    69   {
    70
    71   free(buf); MessageBox("分离文件中,打开自身文件时出错!","错误");
    72
    73   return;
    74
    75   }
    76
    77   out = fopen(temp_exe1, "wb"); //创建第一个绑定的文件
    78
    79   if (out == NULL)
    80
    81   {
    82
    83   free(buf);
    84
    85   MessageBox("分离文件中,创建第一个被绑定文件时出错!","错误");
    86
    87   return;
    88
    89   }
    90
    91   //将文件指针定位到捆绑器程序长度尾部
    92
    93   fseek(myself, modify_data.my_length, SEEK_SET);
    94
    95   //读取第一个绑定文件的长度
    96
    97   if (fread(&prog1_length, sizeof(prog1_length), 1, myself) == 0)
    98
    99   {
    100
    101   free(buf);
    102
    103   MessageBox("分离文件中,读取第一个被绑定文件长度时出错!","错误");
    104
    105   return;
    106
    107   }
    108
    109   //读取最终文件执行方式(同步或异步执行)
    110
    111   if (fread(&SyncFlag, sizeof(int), 1, myself) == 0)
    112
    113   {
    114
    115   free(buf);
    116
    117   MessageBox("分离文件中,读取第一个被绑定文件长度时出错!","错误");
    118
    119   return;
    120
    121   }
    122
    123   //读取第一个文件内容并写入到新建的temp1.exe文件中
    124
    125   while (bytesin = fread(buf, 1, sizeof(buf), myself))
    126
    127   {
    128
    129   if (totalbytes + bytesin > prog1_length)
    130
    131   bytesin = prog1_length - totalbytes;
    132
    133   totalbytes += fwrite(buf, 1, bytesin, out);
    134
    135   }
    136
    137   fclose(out); //关闭第一个绑定文件句柄
    138
    139   #ifdef DEBUG_PRINT
    140
    141   fprintf(stderr, "已复制 %d 字节!\n", totalbytes);
    142
    143   #endif DEBUG_PRINT
    144
    145   totalbytes = 0;
    146
    147   out = fopen(temp_exe2, "wb"); //创建第二个绑定的文件
    148
    149   if (out == NULL)
    150
    151   {
    152
    153   free(buf);
    154
    155   MessageBox("分离文件中,创建第二个被绑定文件时出错!","错误");
    156
    157   return;
    158
    159   }
    160
    161   //将文件指针定位到最终合成文件中的第二个绑定文件头部, 偏移量 ==
    162
    163   //(捆绑器自身文件长度+保存第一个绑定文件长度所占字节数+保存最终文件执行标志所占字节数+第一个绑定文件长度)
    164
    165   fseek(myself,modify_data.my_length+ sizeof(modify_data.my_length) + sizeof(int) + prog1_length, SEEK_SET);
    166
    167   //读取第二个绑定文件内容并写入到新建的temp2.exe文件中
    168
    169   while (bytesin = fread(buf, 1, sizeof(buf), myself))
    170
    171   {
    172
    173   totalbytes += fwrite(buf, 1, bytesin, out);
    174
    175   }
    176
    177   fclose(out); //关闭第二个绑定文件句柄
    178
    179   #ifdef DEBUG_PRINT
    180
    181   fprintf(stderr, "已复制 %d 字节\n", totalbytes);
    182
    183   #endif DEBUG_PRINT
    184
    185   fclose(myself); //关闭最终合成文件句柄
    186
    187   if (totalbytes == 0) { free(buf); MessageBox("分离文件中,在自身文件中没有被分离的对象!","错误");
    188
    189   return;
    190
    191   }
    192
    193   free(buf); //释放缓冲区
    194
    195   //判断前面读取的最终文件执行标志,来决定以何种方式运行它
    196
    197   if(!SyncFlag) //(0 -- 同步执行,1 -- 异步执行)
    198
    199   {
    200
    201   //置为分解后,为同步执行方式
    202
    203   Create_Process(temp_exe1, false);
    204
    205   Create_Process(temp_exe2, false);
    206
    207   }
    208
    209   else
    210
    211   {
    212
    213   //置为分解后,为异步执行方式
    214
    215   Create_Process(temp_exe1, true);
    216
    217   Create_Process(temp_exe2, true);
    218
    219   }
    220
    221   }


      3、判断何时捆绑程序,何时又分解最终合成程序。 

      由于本程序是将自身捆绑程序作为文件头,要绑定文件附加其后方式生成最终合成文件的。所以,只要知道自身捆绑程序的文件长度,再在初始化对话框涵数OnInitDialog()加以判断及可知道是否是最终合成文件(要不要释放内部绑定文件)。本例程用VC6.0采用静态连接方式生成的Release版,文件大小为184K。 

      故判断是捆绑还是释放文件的代码具体实现如下: 

     1   BOOL CBindFileDlg::OnInitDialog() 
    2
    3   {
    4
    5   CDialog::OnInitDialog();
    6
    7   // Add "About..." menu item to system menu.
    8
    9   // IDM_ABOUTBOX must be in the system command range.
    10
    11   ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    12
    13   ASSERT(IDM_ABOUTBOX < 0xF000);
    14
    15   CMenu* pSysMenu = GetSystemMenu(FALSE);
    16
    17   if (pSysMenu != NULL)
    18
    19   {
    20
    21   CString strAboutMenu;
    22
    23   strAboutMenu.LoadString(IDS_ABOUTBOX);
    24
    25   if (!strAboutMenu.IsEmpty())
    26
    27   {
    28
    29   pSysMenu->AppendMenu(MF_SEPARATOR);
    30
    31   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    32
    33   }
    34
    35   }
    36
    37   // Set the icon for this dialog. The framework does this automatically
    38
    39   // when the application''s main window is not a dialog
    40
    41   SetIcon(m_hIcon, TRUE); // Set big icon
    42
    43   SetIcon(m_hIcon, FALSE); // Set small icon
    44
    45   //在此初始化渐变色进度条
    46
    47   m_Progress.SetRange32(1,500);
    48
    49   m_Progress.SetBkColor(RGB(160,180,220));
    50
    51   m_Progress.ShowPercent(true);
    52
    53   m_Progress.SetPos(500);
    54
    55   //初始置各文件名变量为空
    56
    57   strFirstFilePath = ""; //要绑定第一个文件名
    58
    59   strSecondFilePath = ""; //要绑定第二个文件名
    60
    61   strFinalFilePath = ""; //最终合成文件名
    62
    63   //初始化变量
    64
    65   prog1_length = 0; //文件长度
    66
    67   his_name = ""; //绑定文件名
    68
    69   buf = NULL; //缓冲区置空
    70
    71   //获取自身文件名到my_mane变量中
    72
    73   ::GetModuleFileName(0, my_name, sizeof(my_name));
    74
    75   struct _stat ST;
    76
    77   _stat(my_name, &ST); //获取自身文件信息(长度) //在此加入捆绑器程序的最终大小,来判断是绑定文件还是分解执行文件
    78
    79   //当发现自身文件大小大于原大小184K时,为释放内部合成文件
    80
    81   if(ST.st_size > 184*1024)
    82
    83   {
    84
    85   Unbind(); //分离文件并运行
    86
    87   exit(0); //直接退出程序,不显示捆绑程序画面
    88
    89   }
    90
    91   return TRUE; // return TRUE unless you set the focus to a control
    92
    93   }


      作者:未来工作室(Future Studio) 

    转载于:https://www.cnblogs.com/keis/archive/2011/09/20/2182739.html

    展开全文
  • VC6.0一个控制台工程,含有多个C++源文件,每个文件有一个main函数,如何选择哪个main被运行
  • 如何多个文件捆绑成一个可执行文件作者:未来工作室(Future Studio)徐景周 下载示例程序代码 将多个文件合并成一个最终可执行文件,运行这个最终文件时,就相当于运行了合并前的多个文件。 这种程序在...

    如何将多个文件捆绑成一个可执行文件
    作者:未来工作室(Future Studio)
    徐景周

    下载示例程序代码

        将多个文件合并成一个最终可执行文件,运行这个最终文件时,就相当于运行了合并前的多个文件。

    这种程序在木马程序合并中会经常用到,你想知道它是怎么用程序实现的么?下面我就用我用VC6.0做的

    一个文件捆绑器的例子代码来告诉你,程序运行后界面如下:
    0 && image.height>0){if(image.width>=700){this.width=700;this.height=image.height*700/image.width;}}" height=279 src="http://www.vckbase.com/vckbase/vckbase12/images/1221001.gif" width=266 border=0>
    图一

        基本组成思想:其实,其中的构成思想非常简单。建立一个新的二进制文件,先写入你的捆绑程序

    的数据和其文件长度,再写入你要捆绑的第一个文件的数据和其文件长度,后再直接写入你要捆绑的第

    二个文件的数据和文件长度……,最后就可直接写入你要捆绑的最后一个文件的数据(不需其文件长度)。

    最终文件被执行时,也就是将上面的方法思想倒过来既可。(下面实例仅告诉你如何实现二个文件的捆绑,

    至于多个文件的捆绑,读者只需略加改动既可,详情请细看下载后的实例代码。)

    下面我来讲讲如何具体将其来实现:
    1、捆绑多个文件为一个可执行程序
        先得到自身捆绑程序的文件长度和第一个要捆绑文件的文件长度,枚举第一个要捆绑文件有无图标,

    有的话就用它做为最终生成文件的图标,否则用自身捆绑程序所带默认图标做最终生成文件的图标。在

    新建二进制文件中写入自身捆绑程序的数据和其文件长度,再写入第一个要捆绑文件的数据及其文件长

    度,最后直接写入第二个文件的数据既可。
    捆绑涵数代码实现如下:
    //绑定多个文件为一个可执行文件

    bool CBindFileDlg::Bind_Files()
    {
         FILE* myself;   //自身文件
         FILE* out;      //最终合成文件
         FILE* in;       //待绑定文件
         int bytesin;
         int totalbytes = 0;
         struct _stat ST;
         unsigned int finder = 0x12345678;
         unsigned int i, k;
    	 int l=1;                //状态显示
    	 char buff[20];         //状态显示
    
         his_name = strFirstFilePath; //第一个绑定的文件名
    
         _stat(my_name, &ST);
         modify_data.my_length = ST.st_size;
         if (modify_data.my_length == 0)
         {
              MessageBox("绑定文件中,自身文件长度为零时出错!","错误");
    		  return false;
         }
    
         buf = (BYTE *)malloc(modify_data.my_length);
         if (buf == NULL)
         {
              MessageBox("绑定文件中,分配自身文件长度时出错!","错误");
    		  return false;
         }
    
         myself = fopen(my_name, "rb");  //打开自身文件
         if (myself == NULL)
         {
              free(buf);
              MessageBox("绑定文件中,打开自身文件时出错!","错误");
    		  return false;
         }
    
         bytesin = fread(buf, 1, modify_data.my_length, myself);
         fclose(myself);
    
         if (bytesin != modify_data.my_length)
         {
              free(buf);
              MessageBox("绑定文件中,不能完全读取自身文件内容时出错!","错误");
    		  return false;
         }
    
         for (i = 0; i < modify_data.my_length - sizeof(finder); i += sizeof(finder))
         {
              for (k = 0; k < sizeof(finder); k++)
              {
                   if (buf[i+k] != ((BYTE*)&finder)[k])
                        break;
              }
              if (k == sizeof(finder))   //定位并保存自身数据文件大小
              {
                   memcpy(buf+ i, &modify_data, sizeof(modify_data));
                   break;
              }
         }
    
         if (i >= modify_data.my_length - sizeof(finder))
         {
              free(buf);
              MessageBox("绑定文件中,不能定位自身文件时出错!","错误");
    		  return false;
         }
    
         if (_stat(strFirstFilePath, &ST) != 0 || ST.st_size == 0)
         {
              free(buf);
              MessageBox("绑定文件中,读取第一个要绑定文件时出错!","错误");
    		  return false;
         }
    
         list_my_icons();
    
         out = fopen(strFinalFilePath, "wb"); //创建最终合成文件
         if (out == NULL)
         {
              free(buf);
              MessageBox("绑定文件中,创建绑定后生成的合成文件时出错!","错误");
    		  return false;
         }
    
         totalbytes += fwrite(buf, 1, bytesin, out);
    
         in = fopen(strFirstFilePath, "rb");  //打开第一个要绑定的文件
         if (in == NULL)
         {
              free(buf);
              MessageBox("绑定文件中,打开第一个要绑定文件时出错!","错误");
    		  return false;
         }
    
    	 //写入第一个要绑定文件的长度到合成文件中
         totalbytes += fwrite(&ST.st_size, 1, sizeof(ST.st_size), out);
    
    	 //写入最终分解后文件执行方式的标志位(同步或异步执行)
    	 UpdateData(TRUE);  //传控件值到变量m_Sync中
    	 totalbytes += fwrite(&m_Sync, 1, sizeof(int), out);
    
         while (bytesin = fread(buf, 1, modify_data.my_length, in))
         {
              totalbytes += fwrite(buf, 1, bytesin, out);
         }
         fclose(in); //关闭第一个绑定文件句柄
    
    	 //设置进度条显示
         m_Progress.SetRange(0,500);
         for (int m = 0; m < 500; m++)
    		m_Progress.SetPos(m);
    	 m_Parts = _ltoa(l, buff, 10);
    	 m_Parts += _T("个文件已绑定");
    	 UpdateData(FALSE);
    	 l++;
    
         in = fopen(strSecondFilePath, "rb");   //打开第二个要绑定的文件
         if (in == NULL)
         {
              free(buf);
              MessageBox("绑定文件中,打开第二个要绑定文件时出错!","错误");
    		  return false;
         }
         while (bytesin = fread(buf, 1, modify_data.my_length, in))
         {
              totalbytes += fwrite(buf, 1, bytesin, out);
         }
    
    	 //设置进度条显示
         m_Progress.SetRange(0,500);
    	 for (int n = 0; n < 500; n++)
    		m_Progress.SetPos(n);
    	 m_Parts = _ltoa(l, buff, 10);
    	 m_Parts += _T("个文件已绑定");
    	 UpdateData(FALSE);
    	 l++;
    
         fclose(in);  //关闭第二个绑定文件句柄
         fclose(out); //关闭最终合成文件句柄
         free(buf);   //释放缓冲区
    
    	 return true;
    }

    2、释放最终合成文件并同时运行它们。
       打开自身文件,从中得到自身捆绑程序的文件长度,便可将文件指针定位到第一个被捆绑文件的位置,

    读取其文件长度和其数据,将其读出数据写入第一个新建文件中。同样,通过已读取的自身捆绑程序文件

    长度和第一个被捆绑文件的文件长度加上其保存这两个文件长度值的字节数,既可准确定位第二个被捆绑

    文件的位置,读取其数据,写入到第二个新建文件中。同时,运行这两个文件,最后再删除这两个文件既

    可。

    释放最终合成文件的代码具体实现如下:
    //分解已合并的文件,同时运行它们

    void CBindFileDlg::Unbind()
    {
         FILE* myself;         //自身文件
         FILE* out;            //分解后文件
         int bytesin;
         int totalbytes = 0;
         char temp_exe1[] = "temp1.exe";  //分解后的绑定文件名一
         char temp_exe2[] = "temp2.exe";  //分解后的绑定文件名二
    	 int  SyncFlag;        //文件最终执行标志
    
         buf = (BYTE*)malloc(modify_data.my_length);
    
         myself = fopen(my_name, "rb");  //打开最终合成文件
         if (myself == NULL)
         {
    		 free(buf);
             MessageBox("分离文件中,打开自身文件时出错!","错误");
    		 return;
         }
    
         out = fopen(temp_exe1, "wb");   //创建第一个绑定的文件
         if (out == NULL)
         {
    		  free(buf);
              MessageBox("分离文件中,创建第一个被绑定文件时出错!","错误");
    		  return;
         }
    
    	 //将文件指针定位到捆绑器程序长度尾部
         fseek(myself, modify_data.my_length, SEEK_SET);
    
    	 //读取第一个绑定文件的长度 
         if (fread(&prog1_length, sizeof(prog1_length), 1, myself) == 0)
         {
    		 free(buf);
             MessageBox("分离文件中,读取第一个被绑定文件长度时出错!","错误");
    		 return;
         }
    
    	 //读取最终文件执行方式(同步或异步执行)
         if (fread(&SyncFlag, sizeof(int), 1, myself) == 0)
         {
    		 free(buf);
             MessageBox("分离文件中,读取第一个被绑定文件长度时出错!","错误");
    		 return;
         }
         
    	 //读取第一个文件内容并写入
         while (bytesin = fread(buf, 1, sizeof(buf), myself))
         {
              if (totalbytes + bytesin > prog1_length)
                   bytesin = prog1_length - totalbytes;
              totalbytes += fwrite(buf, 1, bytesin, out);
         }
         fclose(out);  //关闭第一个绑定文件句柄
    
    #ifdef DEBUG_PRINT
         fprintf(stderr, "已复制 %d 字节!\n", totalbytes);
    #endif DEBUG_PRINT
    
         totalbytes = 0;
         out = fopen(temp_exe2, "wb");      //创建第二个绑定的文件
         if (out == NULL)
         {
    		  free(buf);
              MessageBox("分离文件中,创建第二个被绑定文件时出错!","错误");
    		  return;
         }
    
    	 //将文件指针定位到最终合成文件中的第二个绑定文件头部, 偏移量 ==
    	 //(捆绑器自身文件长度+保存第一个绑定文件长度所占字节数+保存最终文件执行标志所占字节数+第一个
    	 // 绑定文件长度)
         fseek(myself, 
    	modify_data.my_length + sizeof(modify_data.my_length) + sizeof(int) + prog1_length, 
    	SEEK_SET);
        
    	 //读取第二个绑定文件内容并写入
    	 while (bytesin = fread(buf, 1, sizeof(buf), myself))
         {
              totalbytes += fwrite(buf, 1, bytesin, out);
         }
         fclose(out);  //关闭第二个绑定文件句柄
    
    #ifdef DEBUG_PRINT
         fprintf(stderr, "已复制 %d 字节\n", totalbytes);
    #endif DEBUG_PRINT
    
         fclose(myself); //关闭最终合成文件句柄
    
         if (totalbytes == 0)
         {
    		  free(buf);
              MessageBox("分离文件中,在自身文件中没有被分离的对象!","错误");
    		  return;
         }
    
    	 free(buf);   //释放缓冲区
    
    	 if(!SyncFlag) //0 -- 同步执行,1 -- 异步执行
    	 {
    	   //置为分解后,为同步执行方式
           Create_Process(temp_exe1, false); 
           Create_Process(temp_exe2, false);
    	 }
    	 else
    	 {
           //置为分解后,为异步执行方式
           Create_Process(temp_exe1, true); 
           Create_Process(temp_exe2, true);
    	 }
    }
    其中具体实现细节问题,可在下载实例代码后,仔细查看既可(内有详细注释)。
    展开全文
  • 你也许会遇到到这样一个问题?当你有一个较大的软件,而无法用一张软盘将其全部拷下时,你也许会想 到该将它分解开,...基本构成思想:文件分割的基本思想比我之前发表的另一篇文章《如何多个文件合并为一个可执行...

    你也许会遇到到这样一个问题?当你有一个较大的软件,而无法用一张软盘将其全部拷下时,你也许会想 到该将它分解开,分盘拷回去后,再将它们合并起来。现在的这种分割工具很多,你想自己动手做一个适合自己的分割工具么?下面就让我用以前用VC做的一个<袖珍文件分割器>的例程来告诉你吧!程序运行后界面如下:

    e79c1de5ac8d4a329ed5f8521ae9b615.jpg

    基本构成思想:文件分割的基本思想比我之前发表的另一篇文章《如何将多个文件合并为一个可执行程序》的 构成思想简单多了,它主要也分为分割文件和合并分割后的文件二大部分。分割文件,将原文件按指定分割大小进行等分,然后顺序读取其指定分割大小数据后到写 到各自的新建文件中。合并文件,将各分割后的文件顺序读取后,写入到一个文件中既可。分割文件时,打开文件,读取指定的分割大小一段数据,写入到一新建文 件中,接着再读同样大小的一段数据,再写入到一新建文件中,直到读出文件最后一部分数据,写入到最后一个新建文件中。对每一个分割后的新建文件名,采 用原文件名前加数字信息的方法,按分割的顺序,按个加上一数字标识信息,以便合并时使用。分割文件的部分代码实现如下:

    //文件分割涵数
    int CFileSpltDlg::SplitMe() 
    {
    	......
    	//分割文件
    	do {
    		//动态建立一个新建文件名的前的数字
    		name = _ltoa(l, buff, 10);
    		name += _T("_");
    		CString newpath; 
    
    		//判断选择目录未尾是否已有"\"符
    		if(m_targetpath.Right(1)==''\\'')
    			newpath = m_targetpath;
    		else
    			newpath = m_targetpath + _T("\\");
    		if (!destFile.Open(newpath + name + m_SourceFile.GetFileName(),  
    			CFile::modeWrite		| 
    			CFile::shareExclusive	| 
    			CFile::typeBinary		|
    			CFile::modeCreate, &ex)) {
    			TCHAR szError[1024];
    			ex.GetErrorMessage(szError, 1024);
    			::AfxMessageBox(szError);
    			m_SourceFile.Close();
    			return 1;
    		}
    		do {
    			dwRead = m_SourceFile.Read(buffer, nCount);
    			destFile.Write(buffer, dwRead);
    		}//当文件小于指定要分割的大小时
    		while (dwRead > 0 && destFile.GetLength() < newlen); 
    		destFile.Close();
    	
    		l++;
    		UpdateWindow();
    	}while (dwRead > 0);
    	m_SourceFile.Close();
       	return 0;
    }  
    

    合并文件时:和上面分割所采用的方法相反,将各个分割后的小文件读出后,按其分割后文件名前数字大小的顺序,按个写入到新建的文件中,这一新建文件的名字,为去掉分割后文件前面数字部分后的文件名(既原文件名)。合并文件的部分代码实现如下:

    // 文件合并函数          
    int CFileSpltDlg::MergeMe() 
    {
    	......
    	//开始合并文件
    	do {
    		//自动定位分割文件名前的数字信息
    		pref = _ltoa(l, buff, 10);
    		pref += _T("_");
    		//打开新的分割文件
    		if (!m_SourceFile.Open(newpath + pref + m_filename,  
    			CFile::modeRead		| 
    			CFile::shareExclusive	| 
    			CFile::typeBinary, &ex)) {
    			TCHAR szError[1024];
    			ex.GetErrorMessage(szError, 1024);
    			destFile.Close();
    			m_path = _T("");
    			m_filename = _T("");
    			newpath = _T("");
    			UpdateData(FALSE);
    			return 0;
    		}
    		else
    			//形成一个新的文件名 
    			name = _T(newpath + pref + m_filename);
    		do  {//写入到目标文件中
    			dwRead = m_SourceFile.Read(buffer, nCount);
    			destFile.Write(buffer, dwRead);
    		}while (dwRead > 0);
    
    		m_SourceFile.Close();
    
    		l++;
    		UpdateWindow();
    	}while (l < 500);//little bit dirty solution, but you can always improve it!...
    		
    	return 0;
    }  
    

    以上各部分代码的实现细节,请参看源代码。

    转载于:https://www.cnblogs.com/rogee/archive/2011/03/31/2000479.html

    展开全文
  • VC 如何使程序运行后自己删除自己

    万次阅读 多人点赞 2011-08-12 16:08:01
    有时候,我们需要创建一个运行后能够自己删除自己的可执行程序即自删除程序。很明显如果一进程通过直接调用DeleteFile()来删除自己是不可能的。必须另想办法,经过本人在网上参考很资料后实际测试并集众家之所长...
     有时候,我们需要创建一个运行后能够自己删除自己的可执行程序即自删除程序。很明显如果一个进程通过直接调用DeleteFile()来删除自己是不可能的。必须另想办法,经过本人在网上参考很多资料后实际测试并集众家之所长,发现有二种方法效果比较好。现在将其封装成函数,这样使用将更加容易:

    方法1,调用BAT文件。

    //向指定文件写入文本。如果文件不存在就创建。
    int WriteTextToFile(const char szFileName[], const char *lpszText)
    {
    	FILE *pfile = fopen(szFileName, "w+");
    	if (pfile == NULL)
    		return -1;
    	int nWriteByte = fprintf(pfile, lpszText);
    	fclose(pfile);
    	return nWriteByte;
    }
    void DeleteApplicationSelf()  //可以达到效果
    {
    	const char szFileName[] = "DeleteBat.bat";//使用批处理
    	const char szDeleteBatText[] = "@ echo off\n del %%1\"\n del %%0";
    	
    	//创建BAT文件并写入内容
    	WriteTextToFile(szFileName, szDeleteBatText);
    	
    	//设置本程序进程基本为实时执行,快速退出。
    	SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
    	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
    	//通知资源管理器不显示本程序,当然如果程序没有真正的删除,刷新资源管理器后仍会显示出来的。
        SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, _pgmptr, NULL);
    	
    	//运行bat文件来删除程序
    	char szFilePath[MAX_PATH];
    	sprintf(szFilePath, "\"%s\"", _pgmptr);
    	ShellExecute(NULL, "open", "DeleteBat.bat", szFilePath, NULL, SW_HIDE);
    	
    	ExitProcess(0);
    }

    调用起来非常方便:直接一个DeleteApplicationSelf()就完成了任务。

     

    方法二。调用系统的cmd程序并传入参数。

    void DeleteApplicationSelf()
    {
    	char szCommandLine[MAX_PATH + 10];
    	
    	//设置本程序进程基本为实时执行,快速退出。
    	SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
    	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
    	//通知资源管理器不显示本程序,当然如果程序没有真正的删除,刷新资源管理器后仍会显示出来的。
        SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, _pgmptr, NULL);
    	
    	//调用cmd传入参数以删除自己
    	char szFilePath[MAX_PATH];
    	sprintf(szFilePath, "\"%s\"", _pgmptr);
    	sprintf(szCommandLine, "/c del /q %s", szFilePath);
    	ShellExecute(NULL, "open", "cmd.exe", szCommandLine, NULL, SW_HIDE);
    	
    	ExitProcess(0);
    }

    调用方法与前面相同。

     

    这二种方法都不会出现DOS程序窗口,完全达到了无影无踪的删除效果,更加不会出现有的程序自删除后仍显示程序图标,要刷新资源管理器后才发现程序被删除了。

     

    再对代码作下讲解:

    1._pgmptr 的定义为extern char * _pgmptr,stdlib.h文件对其说明为:points to the module (EXE) name。使用_pgmptr与使用GetModuleFileName(NULL, szExePath, MAX_PATH);来得到程序的路径是等效的。但是,绝对要加上""双引号后才能作参数传给批处理程序,不然会出错。

    2.ShellExecute()最后一个参数为SW_HIDE表示隐藏窗口。

    3.DOS命令del的/q参数表示安静模式,这样删除文件时就不会出现要求用户确认的提示对话框了。

     

    附:二种方法都要加入头文件及lib库

    #include <windows.h>
    #include <stdlib.h>
    #include <shellapi.h>
    #include <shlobj.h>
    
    #pragma comment(lib, "shell32.lib")

     

    展开全文
  • 有时候,我们需要创建一个运行后能够自己删除自己的可执行程序即自删除程序。很明显如果一进程通过直接调用DeleteFile()来删除自己是不可能的。必须另想办法,经过本人在网上参考很资料后实际测试并集众家之所长...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 191
精华内容 76
关键字:

vc如何运行多个文件