工控编程吧
标题:
405上位机VC MFC实现任意文件打包与解包
[打印本页]
作者:
qq263946146
时间:
2016-9-15 13:27
标题:
405上位机VC MFC实现任意文件打包与解包
(, 下载次数: 0)
上传
点击文件名下载附件
实现文件打包与解包
功能展示
文件的打包与解包是程序安装与更新常用到的功能,只要双击一个EXE程序,就可以释放出如图片,DLL,EXE等各种资源,并执行自己特定的功能。我们当前例程通过编写代码利用两种简单方法实现文件的打包与解包,效果如图,点击<将根目录…打包为Data.bin>可以将这些文件全部打包到Data.bin文件中,点击右侧按钮则从此文件解包出全部文件到Temp文件夹中。通过<从本程序解包文件…到根目录>可以从程序自身释放出Data0.bin
要点提示
文件打包,可以事先通过VC编程软件将资源文件载入到工程,编译运行后就可FindResource() LoadResource() LockResource() FreeResource()等函数组合释放资源到磁盘;
1.HRSRC FindResource( HMODULE hModule, LPCTSTR lpName, LPCTSTR lpType);
hModule:处理包含资源的可执行文件的模块。NULL值则指定模块句柄指向操作系统通常情况下创建最近过程的相关位图文件。
lpName:指定资源名称。若想了解更多的信息,请参见注意部分。
lpType:指定资源类型。若想了解更多的信息,请参见注意部分。作为标准资源类型。这个参数的含义同EnumResLangProc\lpType。
返回值:如果函数运行成功,那么返回值为指向被指定资源信息块的句柄。为了获得这些资源,将这个句柄传递给LoadResource函数。如果函数运行失败,则返回值为NULL。
?2.HGLOBAL LoadResource(HMODULE hModule,HRSRC hReslnfo);
hModule:处理包合资源的可执行文件的模块句柄。若hModule为NULL,系统从当前过程中的模块中装载资源。
hReslnfo:将被装载资源的句柄。它必须由函数FindResource或FindResourceEx创建。
返回值:如果函数运行成功,返回值是相关资源的数据的句柄。如果函数运行失败,返回值为NULL
3.LPVOID LockResource(HGLOBAL hResData);
hResDate:被装载的资源的句柄。函数LoadResource可以返回这个句柄。
返回值:如果被装载的资源被锁住了,返回值是资源第一个字节的指针;否则为NULL。
另外一种方法是通过文件操作类Cfile实现文件的打包与解包,具体函数的使用可以参阅MSDN手册,在实现过程中,有用到一函数_access()用于判定文件是否可写,是否可读,是否存在,是否可读写等属性。包含在头文件#include<io.h>中,此函数较少用到但功能很强大。
int _access( const char *path, int mode ); path:文件或目录的路径, mode :指定的模式;如果用指定的模式去判断文件的属性,文件属性不存在则返回-1,存在返回0。如access(path,00)判断文件是否存在,存在返回0,不存在返回-1;
Mode为以下几种值00判断文件是否存在,02判断文件是否有写权限,04判断文件是否有读权限,06判断文件是否有读写权限;
实现功能
1.新建基于对话框的应用程序
2.在主对话框头文件中添加头文件,定义宏结构体,并添加三个自定义函数
#include<io.h>
#define MAX_FILE_COUNT 10// 包文件中最大可容纳的文件个数
typedef struct SMaseFileHeader // 资源包文件头结构
{
UINT uFileFlag; // 包文件头标记: 'MASE'
UINT uFileCount; // 包内文件个数
LONG uFileListOfs; // 文件列表偏移
UINT uMaxFileCount; // 最大子文件个数
LONG uFileSize; // 包文件的大小
}PackHeader;
typedef struct SFilesMessage // 包内文件信息结构
{
LONG uFileOfs; // 本文件在包内的偏移
LONG uFileSize; // 本文件的大小
char szFileName[_MAX_PATH]; // 文件名
}PackFileMsg;
public:
BOOL PackAFile(CString sPackName,CString sFile);//打包文件,sPackName包绝对路径,sFile文件绝对路径
BOOL UnpackAllFiles(CString sPackName,CString sPath);//全部解包,sPackName包绝对路径,sPath文件夹
BOOL ExtractSrc(CString sSrcType,UINT nSrcID, CString sSavePathName, UINT nTYPE=0);//将资源释放为文件
3.在根目录添加文件夹Temp,复制例程的测试用文件Data.bin,主程序.exe,激光刻划.dll, PLC通讯.dll, MachineData.ini到自己工程根目录并载入Data.bin到工程,类型命名为Source,ID命名为IDR_SOURCE1。添加三个按钮<将根目录\r\nMachineData.ini\r\n激光刻划.dll\r\n主程序.exe\r\nPLC通讯.dll\r\n打包为Data.bin><通讯.dll\r\n到文件夹Temp><从本程序解包出文件Data0.bin到根目录>关联点击函数,实现对应功能
void CGkbc8Dlg::OnPakage()
{
char cPath[_MAX_PATH];
GetModuleFileName(NULL,cPath,_MAX_PATH);
CString sPath(cPath);
sPath = sPath.Left(sPath.ReverseFind('\\'));
//<>
PackAFile(sPath+"\\Data.bin",sPath+"\\激光刻划.dll");
PackAFile(sPath+"\\Data.bin",sPath+"\\MachineData.ini");
PackAFile(sPath+"\\Data.bin",sPath+"\\PLC通讯.dll");
PackAFile(sPath+"\\Data.bin",sPath+"\\主程序.exe");
}
void CGkbc8Dlg::OnUnpakage()
{
char cPath[_MAX_PATH];
GetModuleFileName(NULL,cPath,_MAX_PATH);
CString sPath(cPath);
sPath = sPath.Left(sPath.ReverseFind('\\'));
//<>
UnpackAllFiles(sPath+"\\Data.bin", sPath+"\\Temp");
}
void CGkbc8Dlg::OnButton3()
{
char cPath[_MAX_PATH];
GetModuleFileName(NULL,cPath,_MAX_PATH);
CString sPath(cPath);
sPath = sPath.Left(sPath.ReverseFind('\\'));
//<>
if( !ExtractSrc("Source", IDR_SOURCE1,sPath+"\\Data0.bin",0) )
MessageBox("提取文件失败");
}
我们来演示下功能实现的整个过程
[iqiyi]http://player.video.qiyi.com/21a603a3f519b7bb5ad5b4ae71753b47/0/0/w_19rsx1y3i9.swf-albumId=6284504109-tvId=6284504109-isPurchase=0-cnId=12[/iqiyi]
(, 下载次数: 0)
上传
点击文件名下载附件 [weixinlianxi]1[/weixinlianxi]
[note]1[/note]
欢迎光临 工控编程吧 (https://www.gkbc8.com/)
Powered by Discuz! X3.4