自动检查我的应用程序的新版本

时间:2020-03-05 18:51:24  来源:igfitidea点击:

尝试满足客户的功能请求,我希望我的应用程序在Internet可用时,在我们的网站上检查是否有新版本。

问题是我不知道在服务器端必须做什么。

我可以想象我的应用程序(使用Qt在C ++中开发)必须向服务器发送请求(HTTP吗?),但是将如何响应该请求呢?为了通过防火墙,我想我必须使用端口80?这样对吗 ?

或者,对于这种功能,我是否必须要求我们的网络管理员打开一个用于通信的特定端口号?

@pilif:感谢详细回答。还有一些我不清楚的事情:

like
  
  http://www.example.com/update?version=1.2.4
  
  Then you can return what ever you want, probably also the download-URL of the installer of the new version.

我该如何退货?它会是php还是asp页面(我对PHP或者ASP一无所知,我不得不承认)?我如何解码?version = 1.2.4部分以便相应地返回内容?

解决方案

回答

实现此目的的最简单方法是使用libcurl之类的库触发HTTP请求,并下载包含在线版本以及在线可用的新版本的ini或者xml文件。

解析xml文件后,我们可以确定是否需要新版本,并使用libcurl下载新版本并进行安装。

回答

只需在服务器上放置一个(XML)文件,其中包含最新版本的版本号,以及一个URL,即可从中下载新版本。然后,应用程序可以请求XML文件,查看版本是否与其自己的版本不同,然后采取相应的措施。

回答

我认为服务器上的简单XML文件仅用于版本检查就足够了。

这样,我们只需要在服务器和构建系统上的ftp帐户上,就可以在构建新版本后通过ftp发送文件。该构建系统甚至可以直接将安装文件/ zip放到网站上!

回答

在服务器上,我们可能只有一个简单的文件" latestversion.txt",其中包含最新版本的版本号(可能还有下载URL)。然后,客户端只需使用简单的HTTP请求(是,到端口80)读取该文件即可检索http://your.web.site/latestversion.txt,然后可以解析该文件以获得版本号。这样,我们不需要任何精美的服务器代码-我们只需要向现有网站中添加一个简单文件即可。

回答

如果要使其保持真正的基础,只需将version.txt上载到包含整数版本号的Web服务器。根据我们下载的最新version.txt下载该检查,然后只需下载msi或者安装程序包并运行它。

更高级的版本将使用rss,xml或者类似版本。最好使用第三方库来解析rss,并且如果我们愿意,可以包括向用户显示的有关更改的信息。

基本上,我们只需要简单的下载功能。

这两种解决方案都只需要我们访问从客户端发出的端口80。通常,这不需要对防火墙或者网络进行任何更改(在客户端),而我们只需要具有面向Internet的Web服务器(Web托管,托管或者我们自己的服务器都可以在此处使用)。

有几种商业自动更新解决方案可用。我将那些建议留给其他答复者,因为我仅在.net方面具有Click-Once和Updater Application Block的经验(后者不再继续)。

回答

我绝对建议只对网站执行简单的HTTP请求。其他一切注定会失败。

我会向我们网站上包含本地应用程序版本的特定页面发出HTTP GET请求。

喜欢

http://www.example.com/update?version=1.2.4

然后,我们可以返回所需的内容,还可以返回新版本安装程序的下载URL。

为什么不将最新版本的静态文件放到服务器上,让客户端决定呢?因为我们可能希望(或者需要)对流程进行控制。也许将来1.2与服务器不兼容,所以我们希望服务器将更新强制为1.3,但是从1.2.4到1.2.6的更新可能并不重要,因此我们可能希望向客户端提供可选更新。

或者我们想对已安装的基础进行细目分类。

管他呢。通常,我了解到最好在服务器上保留尽可能多的智能,因为服务器是我们最终控制的对象。

这里是在该领域的一些经验,下面是对可能(并相信我)会出错的内容的一小部分预览:

  • 各种个人防火墙应用程序将阻止应用程序发出HTTP请求。
  • 相当多的用户将没有所需的权限才能实际进行更新过程。
  • 即使用户允许旧版本通过其个人防火墙,该工具也会抱怨,因为.EXE已更改,并建议用户不要允许新exe进行连接(用户通常遵守此处安全工具的要求) 。
  • 在托管环境中,我们将被枪杀并绞死(不一定按该顺序),以从Web加载可执行内容,然后实际执行它。

因此,为了使损害尽可能小,

  • 当我们无法连接到更新服务器时,静默失败
  • 在更新之前,请确保我们具有安装目录的写许可权,如果没有,或者根本不进行更新,则警告用户。
  • 为管理员提供一种关闭自动更新的方法。

做我们打算做的事情没什么好玩的,尤其是当我们像我无数次与非技术性用户打交道时。

回答

Pilif的回答很好,我对此也有很多经验,但是我想补充一点:

请记住,如果启动yourapp.exe,则"更新程序"将尝试用最新版本覆盖yourapp.exe。根据操作系统和编程环境(我们已经提到过C ++ / QT,我没有经验),我们将无法覆盖yourapp.exe,因为它将被使用。

我所做的就是创建一个启动器。我有一个MyAppLauncher.exe,它使用配置文件(xml,非常简单)启动"真实exe"。如果存在新版本,启动器会因为未使用"真实exe"而对其进行更新,然后重新启动新版本。

只要记住这一点,我们就可以安全了。

回答

马丁

你当然是对的。但是我将提供带有安装程序的启动程序。或者只是下载安装程序,启动它并尽快退出。原因是启动器中的错误。我们永远不会希望依赖于无法更新的组件(或者忘记将其包括在初始放置中)。

因此,在应用程序更新过程中分发的有效负载只是标准安装程序,而没有任何重要的UI。一旦客户端检查了安装程序有机会成功运行,并且下载了更新程序,它将运行并退出。

然后,更新程序将运行,将其有效内容安装到原始安装目录中,然后重新启动(希望已更新)应用程序。

仍然:该过程很麻烦,并且当应用程序具有广泛的使用重点时,在Windows平台上实现自动更新功能之前,我们最好三思而后行。

回答

我会同意@Martin和@Pilif的回答,但要补充;

请考虑让最终用户决定是否要在此实际安装更新,然后再决定是否安装更新,直到最终使用完该程序为止。

我不知道应用程序的用途/功能,但是当用户需要在其中执行特定操作时会启动许多应用程序,然后又会比启动应用程序烦人,然后被告知已找到新版本,我们不得不等待要下载该软件,请关闭该应用并重新启动。如果程序还有其他可能要更新的资源(参考文件,数据库等),问题将变得更加严重。

我们在大约400家商店中运行着EPOS系统,最初我们认为最好对程序进行现货更新并下载(使用包含与上述建议非常相似的版本号的文件)...好主意。直到所有商店都在大约同一时间(上午8:45-8:50)启动他们的系统,并且我们的服务器受到攻击,可以将20 + Mb的下载下载到400台远程服务器,这将更新本地软件并导致重新开始。混乱,没有人能够交易约10分钟。

不用说,这导致我们随后关闭了"检查更新"功能,并对其进行了重新设计,以使商店可以将更新"延迟"到当天晚些时候。 :-)

编辑:如果有人从ADOBE看书,是出于上帝的缘故,为什么该死的acrobat读者为什么在我只想启动阅读文档时却坚持尝试下载更新和废话?它在启动时是否足够慢,并且足够膨胀,而又不会浪费我的生命另外20至30秒,每次我想阅读PDF时都在寻找更新?
不要使用自己的软件? :-)

回答

如果我们将文件保存在example.com上的更新目录中,则根据前面提到的请求,此PHP脚本应为我们下载文件。 (更新将是yourprogram.1.2.4.exe

$version = $_GET['version'];    
$filename = "yourprogram" . $version . ".exe";
$filesize = filesize($filename);
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: post-check=0, pre-check=0");
header("Content-type: application-download");
header('Content-Length: ' . $filesize);
header('Content-Disposition: attachment; filename="' . basename($filename).'"');
header("Content-Transfer-Encoding: binary");

这使Web浏览器认为它正在下载应用程序。

回答

在php中,事情很简单:

<?php
    if (version_compare($_GET['version'], "1.4.0") < 0){
        echo "http://www.example.com/update.exe";
    }else{
        echo "no update";
    }
?>

如果可以的话,我们可以扩展它,以便在脚本中不会对当前可用的版本进行硬编码,但这仅是为了说明这一点。

在应用程序中,我们将具有以下伪代码:

result = makeHTTPRequest("http://www.example.com/update?version=" + getExeVersion());
if result != "no update" then
    updater = downloadUpdater(result);
    ShellExecute(updater);
    ExitApplication;
end;

通过指定PHP脚本可以返回的内容来告诉客户端它是否是重要的,强制性的更新,可以随意扩展"协议"。

或者,我们可以添加一些文本以显示给用户,其中可能包含有关更改内容的一些信息。

可能性是无限的。

回答

我的Qt应用仅使用QHttp从我的网站上读取了包含最新版本号的小型XML文件。如果该值大于当前版本号,则可以选择转到下载页面。很简单。工作正常。