自动检查我的应用程序的新版本
尝试满足客户的功能请求,我希望我的应用程序在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文件。如果该值大于当前版本号,则可以选择转到下载页面。很简单。工作正常。