QQ登录

只需一步,快速开始

406上位机VC MFC实现离线安装包更新

[ 复制链接 ]

406上位机VC MFC实现离线安装包更新

406上位机VC MFC实现离线安装包更新

实现离线安装包更新
功能展示
我们平时电脑软件都是在线更新,但工控机上的软件一般都是使用更新包离线升级,我们当前例程就实现了指定程序离线升级功能,效果如图,点击更新按钮,程序会依次执行 终止要更新的程序运行,从注册表获取要更新程序的安装目录,从实例中解包全部新版本文件到缓存目录并复制到安装目录,最后清理缓存目录完成更新

要点提示
例程中,指定程序离线功能的实现,主要过程为 :
1.将全新新版本文件打包生成EXE可执行文件即生成一个更新包;
2.运行EXE文件,用户允许升级后检查及退出运行中要更新的程序;
3.从注册表获取要更新程序的安装目录;
4.从更新包程序中解包文件到缓存文件,并复制到安装目录进行文件更新;
5.清空缓存目录释放出的文件,完整更新;

1.解包与打包功能使用了上一例程中的函数,主要是PackAFile () UnpackAllFiles () ExtractSrc ();
2.要更新程序的终止运行是通过遍历系统运行中的程序,将程序名与我们要终止运行的程序名比对,名称相同则调用函数TerminateProcess()终止其运行,例程是通过KillProgram(CString sExeName)实现, sExeName为要终止的程序名如gkbc8.exe;
3.从注册表获取要更新程序的安装目录是通过遍历注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall键下的键名及指定程序名进行对比,相同则进一步读取此键下特定的键值项,获取其安装目录;例程是通过GetProgramPath()实现;
4.从缓存目录中获取解包出的全部文件及全部文件的函数是通过函数GetNewFiles()和DeleteDirectory()实现

实现功能
1.新建基于对话框的应用程序
2.与前一例程一样在主对话框头文件包含头文件及结构体申明,以及自定义的变量与函数

#include<io.h>
#include <afxtempl.h>
#include "tlhelp32.h"
#include <shlwapi.h>
#pragma comment(lib,"shlwapi.lib")
#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 KillProgram(CString sExeName="gkbc8.exe");//未运行返回真
void GetProgramPath(CString sKeyName="gkbc8");//从注册表读取要更新的目录
void GetNewFiles();//获得全部新文件名
void DeleteDirectory(CString strDir);//删除整个目录
void DoUpdate();//执行更新
private:
CString m_TempPath; //解包用临时目录
CString m_sToPath; //目标目录
CStringList m_FileList;//新文件名链
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);//将资源释放为文件
void CToolForUptDlg:oUpdate()
{
if(IDOK != MessageBox("是否执行更新?","提示",MB_OKCANCEL) )
return;
if(!KillProgram("gkbc8.exe") )//关闭指定程序
return;
GetProgramPath("gkbc8");//从注册表获取要更新的目录
GetNewFiles();//获得全部新文件名
//<>
CString sSourceFile,sToFile,sFileName;
POSITION Pos = m_FileList.GetHeadPosition();
while( NULL != Pos)
{
sSourceFile = m_FileList.GetNext(Pos);
sFileName = sSourceFile;
sFileName = sFileName.Right(sFileName.GetLength()-sFileName.ReverseFind('\\'));
sToFile = m_sToPath+sFileName;
if(!::CopyFile(sSourceFile,sToFile,FALSE) )//系统文件操作先获得管理权限
{
int nError =GetLastError();
sSourceFile.Format("更新时复制失败,代码: %d",nError);
MessageBox(sSourceFile);
return;
}
:eleteFile(sSourceFile);
}
DeleteDirectory(m_TempPath);//删除释放用临时文件
}
3.复制根目录文<件测试(安装来测试).exe><Data.bin>到自己工程根目录,并将Data.bin载入到工程类型命名为SOURCE,资源ID不改变既IDR_SOURCE1。
4.添加按钮<执行更新>关联点击函数调用DoUpdate()执行更新
void CToolForUptDlg::OnButton3() { DoUpdate();//执行更新}



我们来演示下功能实现的整个过程


  

您的支持是我们创作的动力!  

  

您可花点闲钱积分自助任意充值

  

成为VIP会员 全站资源任意下载永久更新!



回复

使用道具 举报

快速回复 返回列表 客服中心 搜索