65.9K
CodeProject 正在变化。 阅读更多。
Home

TU:项目的易更新库

starIconstarIconstarIconstarIconstarIcon

5.00/5 (7投票s)

2019年8月3日

CPOL

4分钟阅读

viewsIcon

14621

使用完整或增量更新实时更新您的 Windows 项目

引言

我讨厌那些不会自动更新的应用程序。真的。这是一个可以为您自动完成所有操作的库。您只需要一个能够运行 PHP 的 Web 服务器来存储更新,仅此而已!

特点

  • 完整或差异更新
  • 静默更新
  • 逐项压缩
  • 分离数据库

Web 服务器准备

您需要一个合适的 PHP 版本。我的服务器运行的是 PHP 7.3,但该脚本在旧版本中也能正常工作。它使用 SQLite3 创建数据库,您可以编辑它以支持 MySql 或其他任何数据库。

  1. 编辑 tu.php 以更改数据库名称和默认管理员用户名 + 密码。
  2. tu.php 上传到您的服务器。
  3. 转到 tu.php?admin。那里有一个简单的管理面板,允许管理项目。要创建一个项目,您需要指定一个名称和一个上传密码。
  4. 创建后,管理面板会生成一个 GUID,该 GUID 将被放入 Windows 应用程序中以引用该项目。

PHP 管理面板

管理员面板显示

  • 清空数据库的选项
  • 分割数据库的选项。分割的数据库会将文件数据放在数据库之外,这样您的 SQLite3 数据库就不会增长。 
  • 如果已分割,则有重新合并数据库的选项。
  • 包含以下内容的工程列表
    • 名称
    • ID
    • 大小
    • 直接链接
    • 压缩/解压缩的选项
    • 直接下载次数
    • 补丁数量
    • 检查次数

最后一次统计数据在上传后重置。

Windows 应用程序

  • 包含 tu.hpp
  • 实例化一个 TU::TU 对象
TU(const char* prjg,const wchar_t* host,const wchar_t* path,
bool SSL = false,unsigned short Port = 0,DWORD flg = 0,const wchar_t* un = 0,
const wchar_t* pwd = 0,const wchar_t* uploadpwd = 0)

参数

  • tu.php 管理面板创建的唯一项目 GUID
  • 主机名
  • PHP 脚本的路径
  • SSL 的 true/false
  • 可选端口(如果为 0,则使用 80 或 443)
  • InternetConnect() 函数的标志
  • 服务器的可选用户名/密码
  • 如果您计划上传文件,则上传密码

之后,使用 AddFiles() 成员添加将被库引用的文件。每个文件都有一个本地路径和一个远程 ID (guid)

vector<tuple<wstring, string>> tux;

auto a = L"m.docx";
tux.emplace_back(make_tuple<wstring, 
string>(forward<wstring>(a), string("A44BC1B3-D919-4835-A7D8-FC633EB7B7EC")));
auto b = L"m.pdf";
tux.emplace_back(make_tuple<wstring, 
string>(forward<wstring>(b), string("A44BC1B3-D919-4835-A7D8-FC633EB7B7ED")));
tu.AddFiles(tux);

还有一个 AddSelf() 来自动添加您自己的可执行文件。

将更新上传到您的服务器

HRESULT Upload
     (std::function<HRESULT(size_t sent, size_t total, void*)> func = nullptr,void* lp = 0);

HRESULT hr = tu.Upload();

这使用我漂亮的 REST 库与 PHP 脚本通信,并使用 ZipUtils 压缩要上传的数据,仅此而已。通常,您不会从您的应用程序中调用此函数,因为它需要上传密码,您也不希望其他人通过嗅探连接来获取该密码。通常,您将使用一个单独的“上传器”。该函数将所有项目压缩到一个 ZIP 文件中,然后将其发送到 tu.php

github 仓库中有一个示例“上传器”,它从 XML 配置文件中上传项目。

该函数接受一个可选的回调函数,只要您的文件正在上传,就会重复调用该函数。从它返回 E_FAIL 以停止上传。

检查更新

HRESULT Check();
HRESULT hr = tu.Check();

如果所有已检查的文件都是最新的,则返回 S_OK,如果任何文件需要更新,则返回 S_FALSE

更新

HRESULT DownloadFull(std::function<HRESULT
     (unsigned long long, unsigned long long, void*)> func = nullptr, void* lp = 0);

自动下载所有需要下载并更新的文件。此函数也适用于正在使用的文件(例如您自己的应用程序),方法是将当前文件移动到 .OLD 文件中,创建一个新的目标,然后标记旧文件以进行删除。这样,您就可以通过几行代码轻松地自我更新,并且您的用户永远不会注意到它:下次应用程序启动时,更新就会在那里。

差异检查

通常,您只需要重新编译,因为一个简单的错误,但您的 EXE 已经有 10MB。当只有一小部分文件不同时,重新下载整个文件不是很可惜吗?

在这里,我的好 DIFF 库发挥了作用。实际上,TU::Upload() 不仅将您的数据上传到服务器,还为每个项目计算一个签名并上传它。现在您可以检查

HRESULT CheckWithSigs(std::function<HRESULT
     (unsigned long long, unsigned long long, void*)> func = nullptr, void* lp = 0);

此函数类似于简单的 Check(),但它还会下载需要更新的文件的签名。在函数返回 S_FALSE 以便您知道需要更新后,调用

HRESULT DownloadDiff(std::function<HRESULT
     (unsigned long long, unsigned long long, void*)> func = nullptr, void* lp = 0);

此函数的行为与 Download() 完全相同,但它只请求服务器上更改的部分,而不是整个下载。因此,使用 DIFF 库将更快地更新您的文件。好的一点是它以差异方式工作,而不是增量方式。这意味着,无论本地项目有多旧,该函数都会计算其不同的部分并从服务器请求它。当然,如果本地项目不存在,该函数将完全重新下载它。

一次性操作

void OneOff(const char* r,bool RunNow = false,HICON hIc = LoadIcon(0,IDI_INFORMATION),bool NoDiff = false);

允许单个 EXE 在一行中检查、下载并更新自身,并具有图标支持和下载对话框。 一行更新!

包含 tu.hpp(其中还包括 diff.hzipall.hrest.h),您就可以开始使用了!

历史

  • 2019 年 8 月 4 日:首次发布
© . All rights reserved.