开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 811|回复: 21
收起左侧

[2025开源大赛(第八届)] win32开发的全自动更新系统支持XP,win7-8-10-11

[复制链接]
发表于 4 天前 | 显示全部楼层 |阅读模式   上海市上海市
分享源码
界面截图: -
是否带模块: -
备注说明: -
本帖最后由 2533 于 2025-10-3 21:08 编辑

QQ20251002-223955.png

QQ20251002-223942.png
WIN32代码开源  除了一张图片 就在无其他 XP版本演示 XP系统下载支持HTPP 不支持HTTPS 所以更新组件批量处理  里面的下载地址 必须是 HTTP
Win32vn.exe "我的软件" "MySoftware.exe" "3.0.0" "http://www.xxx.com/test.exe" "true" "./MySoftware.exe"   



123.gif

win7版本演示 光速更新

123.gif

[C++] 纯文本查看 复制代码
#include <windows.h>
#include <gdiplus.h>
#include <urlmon.h>
#include <process.h>  // 用于_beginthreadex替代std::thread
#include <tlhelp32.h>
#include <wininet.h>  // 添加WinINet支持
#include <string>
#include <vector>
#pragma comment(lib, "gdiplus.lib")
#pragma comment(lib, "urlmon.lib")
#pragma comment(lib, "wininet.lib")

// 因为XP不支持std::thread所以使用_beginthreadex
typedef struct {
        std::wstring url;
        std::wstring savePath;
} DownloadParams;

using namespace Gdiplus;

// 全局变量
ULONG_PTR gdiplusToken;
HINSTANCE hInst;
POINT ptWindowPos = { 0, 0 };
bool isDragging = false;
POINT ptDragStart = { 0, 0 };
int progressValue = 0; // 进度条当前值

// 下载进度全局变量
int g_downloadProgress = 0; // 实际下载进度

// 更新信息结构
struct UpdateInfo {
        std::wstring softwareName;
        std::wstring processName;
        std::wstring version;
        std::wstring downloadUrl;
        bool forceReplace;
        std::wstring installPath;
};

UpdateInfo g_updateInfo;
bool g_isDownloading = false;
bool g_downloadCompleted = false;
bool g_downloadFailed = false; // 添加下载失败标志
std::wstring g_downloadedFilePath;

// 自定义下载回调类,用于更新下载进度
class DownloadProgress_callback : public IBindStatusCallback {
public:
        DownloadProgress_callback() : m_refCount(1) {}

        STDMETHOD(OnProgress)(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR wszStatusText) {
                if (ulProgressMax > 0) {
                        g_downloadProgress = static_cast<int>((static_cast<double>(ulProgress) / static_cast<double>(ulProgressMax)) * 100);
                        // 确保进度值在0-100范围内
                        if (g_downloadProgress > 100) g_downloadProgress = 100;
                        if (g_downloadProgress < 0) g_downloadProgress = 0;
                }
                return S_OK;
        }

        // IUnknown接口实现
        STDMETHOD_(ULONG, AddRef)() {
                return InterlockedIncrement(&m_refCount);
        }

        STDMETHOD_(ULONG, Release)() {
                long count = InterlockedDecrement(&m_refCount);
                if (count == 0) {
                        delete this;
                }
                return count;
        }

        STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject) {
                if (riid == IID_IUnknown || riid == IID_IBindStatusCallback) {
                        *ppvObject = this;
                        AddRef();
                        return S_OK;
                }
                *ppvObject = NULL;
                return E_NOINTERFACE;
        }

        // 实现IBindStatusCallback接口方法
        STDMETHOD(OnStartBinding)(DWORD dwReserved, IBinding *pib) { return E_NOTIMPL; }
        STDMETHOD(GetPriority)(LONG *pnPriority) { return E_NOTIMPL; }
        STDMETHOD(OnLowResource)(DWORD reserved) { return S_OK; }
        STDMETHOD(OnStopBinding)(HRESULT hresult, LPCWSTR szError) { return S_OK; }
        STDMETHOD(GetBindInfo)(DWORD *grfBINDF, BINDINFO *pbindinfo) { return E_NOTIMPL; }
        STDMETHOD(OnDataAvailable)(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed) { return S_OK; }
        STDMETHOD(OnObjectAvailable)(REFIID riid, IUnknown *punk) { return E_NOTIMPL; }

private:
        long m_refCount;
};

// 函数声明
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void PaintContent(HWND hwnd, PAINTSTRUCT& ps);
void DrawContent(Graphics& graphics, const RECT& rcClient, float dpiScale);
Bitmap* LoadPngFromResource(HINSTANCE hInstance, LPCWSTR resourceName);
void DrawProgressBar(Graphics& graphics, const Rect& bounds, int progress, float dpiScale);
void ParseCommandLine(LPWSTR cmdLine);
void DownloadUpdateFile(const std::wstring& url, const std::wstring& savePath);
unsigned int __stdcall DownloadThreadProc(void* param);
void StartDownload();
bool TerminateProcessByName(const std::wstring& processName);
bool ReplaceTargetFile(const std::wstring& sourceFile, const std::wstring& targetPath);

// 应用程序入口
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
        _In_opt_ HINSTANCE hPrevInstance,
        _In_ LPWSTR    lpCmdLine,
        _In_ int       nCmdShow)
{
        hInst = hInstance;

        // 解析命令行参数
        if (wcslen(lpCmdLine) > 0) {
                ParseCommandLine(lpCmdLine);
        }

        // 初始化COM和GDI+
        HRESULT hr = CoInitialize(NULL);
        if (FAILED(hr)) {
                return FALSE;
        }

        GdiplusStartupInput gdiplusStartupInput;
        GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

        // 注册窗口类
        WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
        wcex.style = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc = WndProc;
        wcex.hInstance = hInstance;
        wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
        wcex.lpszClassName = L"CustomDrawWindow";

        RegisterClassEx(&wcex);

        // 在创建窗口前计算屏幕中心位置
        int screenWidth = GetSystemMetrics(SM_CXSCREEN);
        int screenHeight = GetSystemMetrics(SM_CYSCREEN);
        int windowWidth = 420;
        int windowHeight = 211;

        int posX = (screenWidth - windowWidth) / 2;
        int posY = (screenHeight - windowHeight) / 2;

        // 创建窗口并显示
        HWND hWnd = CreateWindowEx(
                0,
                L"CustomDrawWindow",
                L"GDI+ High DPI Custom Draw Window",
                WS_POPUP,
                posX, posY, // 居中显示的位置
                windowWidth, windowHeight,
                NULL,
                NULL,
                hInstance,
                NULL);

        if (!hWnd)
                return FALSE;

        ShowWindow(hWnd, nCmdShow);
        UpdateWindow(hWnd);

        // 创建一个定时器用于更新进度条
        SetTimer(hWnd, 1, 100, NULL); // 每100ms触发一次

        // 消息循环
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0))
        {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }

        // 清理资源
        GdiplusShutdown(gdiplusToken);
        CoUninitialize();

        return (int)msg.wParam;
}

// 获取当前DPI的辅助函数 (XP兼容版本)
UINT GetWindowDpi(HWND hwnd) {
        HDC hdc = GetDC(hwnd);
        int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
        ReleaseDC(hwnd, hdc);
        return dpiX;
}

// 从资源加载PNG图片
Bitmap* LoadPngFromResource(HINSTANCE hInstance, LPCWSTR resourceName)
{
        // 尝试多种方式加载资源
        HRSRC hResource = NULL;

        // 方式1: 使用PNG类型参数
        hResource = FindResourceW(hInstance, resourceName, L"PNG");

        // 方式2: 如果失败,使用IMAGE类型参数
        if (!hResource) {
                hResource = FindResourceW(hInstance, resourceName, L"IMAGE");
        }

        // 方式3: 如果仍然失败,使用默认资源类型参数
        if (!hResource) {
                hResource = FindResource(hInstance, resourceName, L"PNG");
        }

        // 方式4: 如果全都失败,使用固定ID
        if (!hResource) {
                hResource = FindResource(hInstance, MAKEINTRESOURCE(101), L"PNG");
        }

        if (!hResource) {
                return nullptr;
        }

        // 加载资源
        HGLOBAL hMemory = LoadResource(hInstance, hResource);
        if (!hMemory) {
                return nullptr;
        }

        // 获取资源大小
        DWORD dwSize = SizeofResource(hInstance, hResource);
        if (dwSize == 0) {
                return nullptr;
        }

        VOID* pResourceData = LockResource(hMemory);
        if (!pResourceData) {
                return nullptr;
        }

        // 分配全局内存
        HGLOBAL hBuffer = GlobalAlloc(GMEM_MOVEABLE, dwSize);
        if (!hBuffer) {
                return nullptr;
        }

        VOID* pBuffer = GlobalLock(hBuffer);
        if (!pBuffer) {
                GlobalFree(hBuffer);
                return nullptr;
        }

        // 复制资源数据到内存
        CopyMemory(pBuffer, pResourceData, dwSize);
        GlobalUnlock(hBuffer);

        // 创建IStream
        IStream* pStream = nullptr;
        if (CreateStreamOnHGlobal(hBuffer, FALSE, &pStream) != S_OK) {
                GlobalFree(hBuffer);
                return nullptr;
        }

        // 创建Bitmap
        Bitmap* bitmap = Bitmap::FromStream(pStream);
        pStream->Release();
        GlobalFree(hBuffer);

        if (!bitmap) {
                return nullptr;
        }

        if (bitmap->GetLastStatus() != Ok) {
                delete bitmap;
                return nullptr;
        }

        return bitmap;
}

// 绘制进度条
void DrawProgressBar(Graphics& graphics, const Rect& bounds, int progress, float dpiScale) {
        // 确保进度值在0-100范围内
        if (progress < 0) progress = 0;
        if (progress > 100) progress = 100;

        // 创建圆角矩形路径
        GraphicsPath path;
        int cornerRadius = static_cast<int>(5 * dpiScale);

        // 构建路径
        path.AddArc(bounds.X, bounds.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);
        path.AddArc(bounds.X + bounds.Width - cornerRadius * 2, bounds.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);
        path.AddArc(bounds.X + bounds.Width - cornerRadius * 2, bounds.Y + bounds.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);
        path.AddArc(bounds.X, bounds.Y + bounds.Height - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);
        path.CloseFigure();

        // 绘制进度条背景
        Color backgroundColor(255, 220, 220, 220); // 浅灰色
        SolidBrush backgroundBrush(backgroundColor);
        graphics.FillPath(&backgroundBrush, &path);

        // 绘制进度条填充部分
        if (progress > 0) {
                int fillWidth = static_cast<int>((bounds.Width - 4) * progress / 100.0);
                if (fillWidth > 0) {
                        Rect fillRect(bounds.X + 2, bounds.Y + 2, fillWidth, bounds.Height - 4);

                        // 创建填充部分的圆角矩形路径
                        GraphicsPath fillPath;
                        int fillCornerRadius = cornerRadius > 2 ? cornerRadius - 2 : 1;

                        fillPath.AddArc(fillRect.X, fillRect.Y, fillCornerRadius * 2, fillCornerRadius * 2, 180, 90);
                        fillPath.AddArc(fillRect.X + fillRect.Width - fillCornerRadius * 2, fillRect.Y, fillCornerRadius * 2, fillCornerRadius * 2, 270, 90);
                        fillPath.AddArc(fillRect.X + fillRect.Width - fillCornerRadius * 2, fillRect.Y + fillRect.Height - fillCornerRadius * 2, fillCornerRadius * 2, fillCornerRadius * 2, 0, 90);
                        fillPath.AddArc(fillRect.X, fillRect.Y + fillRect.Height - fillCornerRadius * 2, fillCornerRadius * 2, fillCornerRadius * 2, 90, 90);
                        fillPath.CloseFigure();

                        // 创建垂直线性渐变 (浅蓝色到深蓝色)
                        LinearGradientBrush gradientBrush(
                                PointF(static_cast<Gdiplus::REAL>(fillRect.X), static_cast<Gdiplus::REAL>(fillRect.Y)),
                                PointF(static_cast<Gdiplus::REAL>(fillRect.X), static_cast<Gdiplus::REAL>(fillRect.Y + fillRect.Height)),
                                Color(255, 95, 205, 255),    // 浅蓝色
                                Color(255, 50, 144, 225)     // 深蓝色
                                );
                        graphics.FillPath(&gradientBrush, &fillPath);
                }
        }

        // 绘制边框
        Pen borderPen(Color(255, 180, 180, 180), 1.0f);
        graphics.DrawPath(&borderPen, &path);

        // 绘制进度文本
        WCHAR progressText[32];
        swprintf_s(progressText, L"%d%%", progress);

        Font font(L"Arial", 14 * dpiScale, FontStyleBold);
        SolidBrush textBrush(Color(255, 255, 255, 255));

        // 测量文本大小
        RectF textBounds;
        graphics.MeasureString(progressText, -1, &font, PointF(0, 0), &textBounds);

        // 定位文本
        PointF textPos(
                bounds.X + (bounds.Width - textBounds.Width) / 2,
                bounds.Y + (bounds.Height - textBounds.Height) / 2
                );

        graphics.DrawString(progressText, -1, &font, textPos, &textBrush);
}

// 绘制函数
void PaintContent(HWND hwnd, PAINTSTRUCT& ps) {
        // 获取客户区域
        RECT rcClient;
        GetClientRect(hwnd, &rcClient);

        // 创建内存位图用于双缓冲
        Bitmap doubleBufferBitmap(rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);
        Graphics doubleBufferGraphics(&doubleBufferBitmap);
        doubleBufferGraphics.SetSmoothingMode(SmoothingModeAntiAlias);
        doubleBufferGraphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);

        // 获取当前DPI
        UINT dpi = GetWindowDpi(hwnd);
        float dpiScale = dpi / 96.0f;
        if (dpiScale == 0) dpiScale = 1.0f;

        DrawContent(doubleBufferGraphics, rcClient, dpiScale);

        // 将双缓冲内容绘制到屏幕
        Graphics screenGraphics(ps.hdc);
        screenGraphics.DrawImage(&doubleBufferBitmap, 0, 0);
}

// 绘制窗口内容
void DrawContent(Graphics& graphics, const RECT& rcClient, float dpiScale) {
        // 从资源文件加载背景图片 - 使用专用的背景资源ID
        Bitmap* background = LoadPngFromResource(hInst, L"IDB_PNG1");

        // 如果失败,尝试可能的背景资源ID
        if (!background) {
                background = LoadPngFromResource(hInst, L"PNG1");
        }

        if (!background) {
                background = LoadPngFromResource(hInst, MAKEINTRESOURCE(101)); // 使用资源ID 101作为默认图
        }

        if (!background) {
                background = LoadPngFromResource(hInst, MAKEINTRESOURCE(104)); // 使用背景资源ID
        }

        // 加载成功则绘制背景图片
        if (background && background->GetLastStatus() == Ok) {
                // 获取目标窗口尺寸
                int targetWidth = rcClient.right - rcClient.left;
                int targetHeight = rcClient.bottom - rcClient.top;

                // 直接绘制图片到窗口大小,避免使用缩放版本
                graphics.DrawImage(background, 0, 0, targetWidth, targetHeight);
                delete background;
        }
        else {
                // 如果无法加载背景图片,则绘制纯色背景
                SolidBrush brush(Color(70, 130, 180)); // SteelBlue
                graphics.FillRectangle(&brush, rcClient.left, rcClient.top,
                        rcClient.right - rcClient.left,
                        rcClient.bottom - rcClient.top);

                // 显示错误信息给用户
                Font errorFont(L"Arial", 16 * dpiScale);
                SolidBrush errorBrush(Color(255, 255, 255, 255));
                graphics.DrawString(L"加载背景图片资源失败", -1, &errorFont,
                        PointF(210 * dpiScale, 100 * dpiScale), &errorBrush);
        }

        // 绘制版本文本 (自动计算位置)
        Font titleFont(L"微软雅黑", 10 * dpiScale, FontStyleBold);
        SolidBrush textBrush(Color(255, 255, 255, 255));
        RectF textBounds;

        // 构造显示版本号的文本
        std::wstring versionText = L"当前版本: " + g_updateInfo.version;

        // 只有当版本号不为空时才显示
        if (!g_updateInfo.version.empty()) {
                // 测量文本大小
                graphics.MeasureString(versionText.c_str(), -1, &titleFont, PointF(0, 0), &textBounds);

                // 计算文本位置 (右对齐,直接使用偏移)
                float x = 180 * dpiScale;
                float y = 100 * dpiScale;

                graphics.DrawString(versionText.c_str(), -1, &titleFont, PointF(x, y), &textBrush);
        }

        // 绘制进度条 (位置根据背景LOGO调整)
        Rect progressBarRect(
                static_cast<int>(20 * dpiScale),      // X轴偏移,靠左LOGO旁边
                static_cast<int>(150 * dpiScale),
                static_cast<int>(380 * dpiScale),      // 宽度根据窗口大小调整
                static_cast<int>(30 * dpiScale)
                );
        DrawProgressBar(graphics, progressBarRect, progressValue, dpiScale);
}

// 解析命令行参数
void ParseCommandLine(LPWSTR cmdLine) {
        std::wstring cmd(cmdLine);

        // 先尝试按引号分割参数
        size_t pos = 0;
        std::vector<std::wstring> args;
        std::wstring token;

        // 解析带引号的参数
        while ((pos = cmd.find(L"\"")) != std::wstring::npos) {
                cmd.erase(0, pos + 1);
                pos = cmd.find(L"\"");
                if (pos != std::wstring::npos) {
                        token = cmd.substr(0, pos);
                        args.push_back(token);
                        cmd.erase(0, pos + 1);
                }
        }

        // 解析剩余的无引号参数
        if (!cmd.empty()) {
                // 按空格分割剩余参数
                size_t start = 0;
                size_t end = 0;
                while ((end = cmd.find(L" ", start)) != std::wstring::npos) {
                        std::wstring param = cmd.substr(start, end - start);
                        if (!param.empty()) {
                                args.push_back(param);
                        }
                        start = end + 1;
                }
                // 添加最后的一个参数
                std::wstring lastParam = cmd.substr(start);
                if (!lastParam.empty()) {
                        args.push_back(lastParam);
                }
        }

        if (args.size() >= 6) {
                g_updateInfo.softwareName = args[0];
                g_updateInfo.processName = args[1];
                g_updateInfo.version = args[2];
                g_updateInfo.downloadUrl = args[3];
                g_updateInfo.forceReplace = (args[4] == L"true" || args[4] == L"1");
                g_updateInfo.installPath = args[5];
        }
}

// 使用WinINet的下载函数(更好的XP兼容性)
bool DownloadFileWithWinINet(const std::wstring& url, const std::wstring& savePath) {
        // 初始化WinINet
        HINTERNET hInternet = InternetOpen(L"UpdateClient/1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
        if (!hInternet) {
                return false;
        }

        // 打开URL连接
        HINTERNET hUrl = InternetOpenUrl(hInternet, url.c_str(), NULL, 0, INTERNET_FLAG_RELOAD, 0);
        if (!hUrl) {
                InternetCloseHandle(hInternet);
                return false;
        }

        // 创建本地文件
        HANDLE hFile = CreateFile(savePath.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile == INVALID_HANDLE_VALUE) {
                InternetCloseHandle(hUrl);
                InternetCloseHandle(hInternet);
                return false;
        }

        // 下载并保存数据
        char buffer[4096];
        DWORD bytesRead, bytesWritten;
        bool success = true;
        DWORD totalBytes = 0;
        DWORD contentLength = 0;

        // 获取内容长度
        wchar_t szContentLength[32];
        DWORD dwLength = sizeof(szContentLength);
        if (HttpQueryInfo(hUrl, HTTP_QUERY_CONTENT_LENGTH, szContentLength, &dwLength, NULL)) {
                contentLength = _wtoi(szContentLength);
        }

        while (InternetReadFile(hUrl, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
                if (!WriteFile(hFile, buffer, bytesRead, &bytesWritten, NULL)) {
                        success = false;
                        break;
                }

                totalBytes += bytesRead;

                // 更新进度
                if (contentLength > 0) {
                        g_downloadProgress = static_cast<int>((static_cast<double>(totalBytes) / static_cast<double>(contentLength)) * 100);
                        if (g_downloadProgress > 100) g_downloadProgress = 100;
                }
        }

        CloseHandle(hFile);
        InternetCloseHandle(hUrl);
        InternetCloseHandle(hInternet);

        return success;
}

// 文件下载支持进度更新
void DownloadUpdateFile(const std::wstring& url, const std::wstring& savePath) {
        g_isDownloading = true;
        g_downloadCompleted = false;
        g_downloadFailed = false;
        g_downloadProgress = 0;

        // 尝试使用WinINet下载(更好的XP兼容性)
        bool success = DownloadFileWithWinINet(url, savePath);

        // 如果WinINet失败,尝试使用URLDownloadToFile
        if (!success) {
                // 创建下载回调对象
                DownloadProgress_callback* callback = new DownloadProgress_callback();

                // 使用URLDownloadToFile进行文件下载并设置回调
                HRESULT hr = URLDownloadToFile(NULL, url.c_str(), savePath.c_str(), 0, callback);

                // 释放回调对象
                callback->Release();

                success = (hr == S_OK);
        }

        g_isDownloading = false;
        g_downloadCompleted = success;
        g_downloadFailed = !success;
        g_downloadedFilePath = savePath;

        // 下载完成后将进度设为100%
        if (g_downloadCompleted) {
                g_downloadProgress = 100;
        }
}

// 下载线程过程函数 (XP兼容版本)
unsigned int __stdcall DownloadThreadProc(void* param) {
        DownloadParams* params = static_cast<DownloadParams*>(param);
        DownloadUpdateFile(params->url, params->savePath);
        delete params;
        return 0;
}

// 开始下载
void StartDownload() {
        if (g_updateInfo.downloadUrl.empty()) return;

        // 直接使用installPath作为保存路径
        std::wstring savePath = g_updateInfo.installPath;

        // 确保目录存在
        size_t lastSlash = savePath.find_last_of(L"\\/");
        if (lastSlash != std::wstring::npos) {
                std::wstring directory = savePath.substr(0, lastSlash);
                CreateDirectoryW(directory.c_str(), NULL);
        }

        // 创建参数结构
        DownloadParams* params = new DownloadParams();
        params->url = g_updateInfo.downloadUrl;
        params->savePath = savePath;

        // 创建下载线程 (使用XP兼容的方式)
        HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, DownloadThreadProc, params, 0, NULL);
        if (hThread) {
                CloseHandle(hThread);
        }
}

// 终止指定进程
bool TerminateProcessByName(const std::wstring& processName) {
        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (hSnapshot == INVALID_HANDLE_VALUE) {
                return false;
        }

        PROCESSENTRY32 pe32;
        pe32.dwSize = sizeof(PROCESSENTRY32);

        if (!Process32First(hSnapshot, &pe32)) {
                CloseHandle(hSnapshot);
                return false;
        }

        bool found = false;
        do {
                if (_wcsicmp(pe32.szExeFile, processName.c_str()) == 0) {
                        HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID);
                        if (hProcess != NULL) {
                                TerminateProcess(hProcess, 0);
                                CloseHandle(hProcess);
                                found = true;
                        }
                }
        } while (Process32Next(hSnapshot, &pe32));

        CloseHandle(hSnapshot);
        return found;
}

// 替换文件
bool ReplaceTargetFile(const std::wstring& sourceFile, const std::wstring& targetPath) {
        // 确保目标目录存在
        std::wstring directory = targetPath.substr(0, targetPath.find_last_of(L"\\/"));
        CreateDirectoryW(directory.c_str(), NULL);

        // 复制文件
        return CopyFileW(sourceFile.c_str(), targetPath.c_str(), FALSE) == TRUE;
}

// 窗口过程函数
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        switch (message)
        {
        case WM_PAINT:
        {
                                         PAINTSTRUCT ps;
                                         HDC hdc = BeginPaint(hWnd, &ps);
                                         PaintContent(hWnd, ps);
                                         EndPaint(hWnd, &ps);
        }
                break;

        case WM_TIMER:
        {
                                         // 更新进度条值
                                         if (wParam == 1) {
                                                 // 检查是否有更新信息需要处理
                                                 if (!g_updateInfo.softwareName.empty() && !g_isDownloading && !g_downloadCompleted) {
                                                         // 开始下载
                                                         StartDownload();
                                                 }

                                                 // 检查下载是否完成
                                                 if (g_downloadCompleted) {
                                                         // 下载完成,根据参数决定是否替换
                                                         if (g_updateInfo.forceReplace) {
                                                                 // 强制替换
                                                                 TerminateProcessByName(g_updateInfo.processName);
                                                                 ReplaceTargetFile(g_downloadedFilePath, g_updateInfo.installPath);

                                                                 // 启动新版本程序
                                                                 ShellExecuteW(NULL, L"open", g_updateInfo.installPath.c_str(), NULL, NULL, SW_SHOWNORMAL);

                                                                 // 退出更新程序
                                                                 PostMessage(hWnd, WM_CLOSE, 0, 0);
                                                         }
                                                         else {
                                                                 // 非强制替换,需要提示用户手动确认
                                                                 // 可以在这里添加UI提示
                                                         }

                                                         g_downloadCompleted = false; // 重置状态
                                                 }

                                                 // 只在下载时才更新进度条
                                                 if (g_isDownloading) {
                                                         // 使用实际下载进度更新进度条
                                                         progressValue = g_downloadProgress;
                                                 }
                                                 else if (g_downloadCompleted) {
                                                         // 下载完成,显示100%
                                                         progressValue = 100;
                                                 }
                                                 else if (g_downloadFailed) {
                                                         // 下载失败,显示错误
                                                         progressValue = -1; // 可用特殊值表示错误
                                                 }

                                                 InvalidateRect(hWnd, NULL, FALSE); // 请求重绘
                                         }
        }
                break;

        case WM_LBUTTONDOWN:
        {
                                                   isDragging = true;

                                                   POINT ptMouse;
                                                   ptMouse.x = (short)LOWORD(lParam);
                                                   ptMouse.y = (short)HIWORD(lParam);

                                                   ClientToScreen(hWnd, &ptMouse);
                                                   ptDragStart = ptMouse;

                                                   RECT rcWindow;
                                                   GetWindowRect(hWnd, &rcWindow);
                                                   ptWindowPos.x = rcWindow.left;
                                                   ptWindowPos.y = rcWindow.top;

                                                   SetCapture(hWnd);
        }
                break;

        case WM_LBUTTONUP:
        {
                                                 isDragging = false;
                                                 ReleaseCapture();
        }
                break;

        case WM_MOUSEMOVE:
        {
                                                 if (isDragging && (wParam & MK_LBUTTON)) {
                                                         POINT ptMouse;
                                                         ptMouse.x = (short)LOWORD(lParam);
                                                         ptMouse.y = (short)HIWORD(lParam);

                                                         ClientToScreen(hWnd, &ptMouse);

                                                         POINT ptNewPos;
                                                         ptNewPos.x = ptWindowPos.x + (ptMouse.x - ptDragStart.x);
                                                         ptNewPos.y = ptWindowPos.y + (ptMouse.y - ptDragStart.y);

                                                         SetWindowPos(hWnd, NULL, ptNewPos.x, ptNewPos.y, 0, 0,
                                                                 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
                                                 }
        }
                break;

        case WM_SIZE:
                InvalidateRect(hWnd, NULL, TRUE);
                break;

        case WM_KEYDOWN:
                if (wParam == VK_ESCAPE) {
                        PostMessage(hWnd, WM_CLOSE, 0, 0);
                }
                break;

        case WM_RBUTTONDOWN:
                PostMessage(hWnd, WM_CLOSE, 0, 0);
                break;

        case WM_DESTROY:
                KillTimer(hWnd, 1); // 销毁定时器
                PostQuitMessage(0);
                break;

        default:
                return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
}


这个是批处理文件内容
更新组件        软件名字    被更新的重新进程   版本     下载地址       是否强制更新    存放目录
Win32vn.exe "我的软件" "MySoftware.exe" "3.0.0" "https://xxx.exe" "true" "./MySoftware.exe"   

游客,如果您要查看本帖隐藏内容请回复








123.gif

签到天数: 2 天

发表于 2 小时前 | 显示全部楼层   四川省南充市
感谢分享
回复 支持 反对

使用道具 举报

结帖率:100% (6/6)

签到天数: 1 天

发表于 昨天 13:38 | 显示全部楼层   北京市北京市
感谢分享
回复 支持 反对

使用道具 举报

签到天数: 1 天

发表于 昨天 08:03 | 显示全部楼层   浙江省台州市
111111111111111
回复 支持 反对

使用道具 举报

结帖率:33% (1/3)

签到天数: 4 天

发表于 前天 22:56 | 显示全部楼层   河南省郑州市
666666666666666666
回复 支持 反对

使用道具 举报

结帖率:94% (45/48)

签到天数: 2 天

发表于 前天 19:55 | 显示全部楼层   广东省佛山市
源码及模块
回复 支持 反对

使用道具 举报

结帖率:100% (3/3)

签到天数: 3 天

发表于 前天 18:48 | 显示全部楼层   江苏省苏州市
谢谢分享!!
回复 支持 反对

使用道具 举报

结帖率:91% (86/94)

签到天数: 4 天

发表于 前天 16:28 | 显示全部楼层   湖南省常德市
学习一下
回复 支持 反对

使用道具 举报

签到天数: 5 天

发表于 前天 09:40 | 显示全部楼层   陕西省汉中市
学习一下
回复 支持 反对

使用道具 举报

结帖率:50% (7/14)

签到天数: 4 天

发表于 前天 09:38 | 显示全部楼层   安徽省淮北市
感谢分享,支持开源!!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

关闭

精易论坛 - 有你更精彩上一条 /1 下一条

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报QQ: 793400750,邮箱:wp@125.la
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备2025452707号) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表