|
VC++完整的MFC自动更新程序实现,包含文件下载和安装逻辑
AutoUpdater.cpp
- #include "stdafx.h"
- #include "AutoUpdater.h"
- #include <wininet.h>
- #include <zip.h>
- #include <shlwapi.h>
- BOOL CAutoUpdater::DownloadUpdate(const CString& strUrl) {
- HINTERNET hInternet = InternetOpen(_T("Updater"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
- HINTERNET hFile = InternetOpenUrl(hInternet, strUrl, NULL, 0, 0, 0);
-
- // 创建临时目录
- TCHAR tempPath[MAX_PATH];
- GetTempPath(MAX_PATH, tempPath);
- m_strTempPath = tempPath + CString(_T("update_pkg.zip"));
-
- // 下载文件
- HANDLE hLocalFile = CreateFile(m_strTempPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-
- DWORD bytesRead;
- BYTE buffer[4096];
- while(InternetReadFile(hFile, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
- DWORD bytesWritten;
- WriteFile(hLocalFile, buffer, bytesRead, &bytesWritten, NULL);
- }
-
- CloseHandle(hLocalFile);
- InternetCloseHandle(hFile);
- InternetCloseHandle(hInternet);
-
- return PathFileExists(m_strTempPath);
- }
- BOOL CAutoUpdater::InstallUpdate() {
- // 解压更新包
- CString strExtractPath = m_strTempPath.Left(m_strTempPath.ReverseFind('\\')) + _T("\\update\");
- CreateDirectory(strExtractPath, NULL);
-
- // 使用minizip解压
- unzFile zipfile = unzOpen(CT2A(m_strTempPath));
- if(!zipfile) return FALSE;
-
- unz_global_info global_info;
- unzGetGlobalInfo(zipfile, &global_info);
-
- for(int i=0; i<global_info.number_entry; ++i) {
- char filename[256];
- unz_file_info file_info;
- unzGetCurrentFileInfo(zipfile, &file_info, filename, sizeof(filename), NULL, 0, NULL, 0);
-
- if(unzOpenCurrentFile(zipfile) == UNZ_OK) {
- CString strDestPath = strExtractPath + filename;
- HANDLE hFile = CreateFile(strDestPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-
- BYTE buffer[4096];
- int bytes;
- while((bytes = unzReadCurrentFile(zipfile, buffer, sizeof(buffer))) > 0) {
- DWORD written;
- WriteFile(hFile, buffer, bytes, &written, NULL);
- }
-
- CloseHandle(hFile);
- unzCloseCurrentFile(zipfile);
- }
- unzGoToNextFile(zipfile);
- }
- unzClose(zipfile);
-
- // 替换旧文件
- WIN32_FIND_DATA findData;
- HANDLE hFind = FindFirstFile(strExtractPath + _T("*.*"), &findData);
- if(hFind != INVALID_HANDLE_VALUE) {
- do {
- if(!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
- CString strSrc = strExtractPath + findData.cFileName;
- CString strDest;
- GetModuleFileName(NULL, strDest.GetBuffer(MAX_PATH), MAX_PATH);
- strDest.ReleaseBuffer();
- strDest = strDest.Left(strDest.ReverseFind('\\') + 1) + findData.cFileName;
-
- MoveFileEx(strSrc, strDest, MOVEFILE_REPLACE_EXISTING);
- }
- } while(FindNextFile(hFind, &findData));
- FindClose(hFind);
- }
-
- return TRUE;
- }
复制代码代码说明: - 下载功能使用WinINet API实现HTTP文件下载
- 安装过程包含ZIP解压和文件替换
- 需要链接wininet.lib和minizip库
- 实际使用需添加错误处理和进度回调
- 建议添加文件校验和数字签名验证
注意事项: - 需要准备minizip库处理ZIP解压
- 文件替换可能需要管理员权限
- 生产环境应使用HTTPS确保下载安全
- 建议添加回滚机制防止更新失败
|
|