文摘首页 >> 网页制作·视觉设计·3D STUDIO·FLASH制作·网络攻防·病毒播报·编程开发·系统维护·网站经营·视频剪辑·文摘论坛
 







线




访




 
 ■ 您现在的位置: 福建大学生在线 >> 文摘 >> 系统维护 >> 文摘正文
 
如何将多个文件捆绑成一个可执行文件
作者:未知 文章来源:网络 点击数: 更新时间:2006-7-3 9:51:00


2、 释放最终合成文件并同3、 时运行它们。
打开自身文件,从中得到自身捆绑程序的文件长度,便可将文件指针定位到第一个被捆绑文件的位置,读取其文件长度和其数据,将其读出数据写入第一个新建文件中。同样,通过已读取的自身捆绑程序文件长度和第一个被捆绑文件的文件长度加上其保存这两个文件长度值的字节数,既可准确定位第二个被捆绑文件的位置,读取其数据,写入到第二个新建文件中。同时,运行这两个文件,最后再删除这两个文件既可。
 释放最终合成文件的代码具体实现如下:

//创建分解文件后,运行各分解文件时的进程
void CBindFileDlg::Create_Process(const char* temp_exe, BOOL async)
{
HANDLE hProcess; //进程句柄
HANDLE hThread; //线程句柄
PROCESS_INFORMATION PI; //进程信息
STARTUPINFO SI; //启动信息

memset(&SI, 0, sizeof(SI)); //分配一定的内存
SI.cb = sizeof(SI); //大小赋给启动信息内CB
CreateProcess(temp_exe, NULL, NULL, NULL, FALSE,NORMAL_PRIORITY_CLASS, NULL, NULL, &SI, &PI);
/* --- 暂不用,否则需要保存原始绑定的文件名称
//如果分解后的文件不是执行文件的话,则直接打开它
if(!CreateProcess(temp_exe, NULL, NULL, NULL, FALSE,NORMAL_PRIORITY_CLASS, NULL, NULL, &SI, &PI))
HINSTANCE result =ShellExecute(NULL, _T("open"), temp_exe, NULL,NULL, SW_SHOW);
--- */

hProcess = PI.hProcess;
hThread = PI.hThread;
//异步执行时,执行后不删除分解后的文件;同步执行时,执行后删除分解后的文件
if (!async) //当同步执行时
{
//一直等待,直到当前程序运行进程结束
WaitForSingleObject(hProcess, INFINITE);
unlink(temp_exe); //删除temp.exe文件
}
}

//分解已合并的文件,同时运行它们
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;
}

//读取第一个文件内容并写入到新建的temp1.exe文件中
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);

//读取第二个绑定文件内容并写入到新建的temp2.exe文件中
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);
}
}
3、判断何时捆绑程序,何时又分解最终合成程序。
由于本程序是将自身捆绑程序作为文件头,要绑定文件附加其后方式生成最终合成文件的。所以,只要知道自身捆绑程序的文件长度,再在初始化对话框涵数OnInitDialog()加以判断及可知道是否是最终合成文件(要不要释放内部绑定文件)。本例程用VC6.0采用静态连接方式生成的Release版,文件大小为184K。

故判断是捆绑还是释放文件的代码具体实现如下:
BOOL CBindFileDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog. The framework does this automatically
// when the application''s main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

//在此初始化渐变色进度条
m_Progress.SetRange32(1,500);
m_Progress.SetBkColor(RGB(160,180,220));
m_Progress.ShowPercent(true);
m_Progress.SetPos(500);

//初始置各文件名变量为空
strFirstFilePath = ""; //要绑定第一个文件名
strSecondFilePath = ""; //要绑定第二个文件名
strFinalFilePath = ""; //最终合成文件名

//初始化变量
prog1_length = 0; //文件长度
his_name = ""; //绑定文件名
buf = NULL; //缓冲区置空
//获取自身文件名到my_mane变量中
::GetModuleFileName(0, my_name, sizeof(my_name));

struct _stat ST;
_stat(my_name, &ST); //获取自身文件信息(长度)
//在此加入捆绑器程序的最终大小,来判断是绑定文件还是分解执行文件
//当发现自身文件大小大于原大小184K时,为释放内部合成文件
if(ST.st_size > 184*1024)
{
Unbind(); //分离文件并运行
exit(0); //直接退出程序,不显示捆绑程序画面
}

return TRUE; // return TRUE unless you set the focus to a control
}

其中具体实现细节问题,可在下载实例代码后,仔细查看既可(内有详细注释)。

上一页  [1] [2] 

文摘录入:一叶知秋    责任编辑:一叶知秋 
【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
  • 上一篇文摘:

  • 下一篇文摘:
  • 版权所有:福建大学生在线(www.fjstu.net)All Right Reserved 2003-2006
    福建大学生在线站务组 - 有你的加入更精彩 - 站务成员全年招募中
    网站备案号:闽ICP备05000367号 广告投放QQ:383870619 欢迎商家加盟