2008-09-11 58 views
22

试图兑现来自我们客户的功能请求,我希望我的应用程序在互联网可用时检查我们的网站是否有新版本。自动检查我的应用程序的新版本

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

我可以想象,我的应用程序(使用Qt开发的C++)必须向服务器发送请求(HTTP?),但是如何响应此请求?为了通过防火墙,我想我必须使用端口80?它是否正确 ?

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


@pilif:谢谢您的详细解答。还有一些东西,目前尚不清楚对我来说:

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

然后你就可以回到你什么都想要,新版本的安装程序也可能下载的URL。

我该如何退货?它会是一个PHP或ASP页面(我不知道关于PHP或ASP,我不得不承认)?我该如何解码?version=1.2.4部分才能返回相应的内容?

回答

38

我绝对建议只对您的网站做一个简单的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连接(用户通常符合他们的安全的意愿工具在这里)。
  • 在托管环境中,您将被从网上加载可执行文件并执行该文件,并将其吊起(不一定按此顺序)。

所以要保持损坏尽可能低,

  • 失败默默当您无法连接到更新服务器
  • 更新前,请确保您有写权限的安装目录并警告用户,或者根本不更新。
  • 为管理员提供关闭自动更新的方法。

做你即将做的事情没有什么乐趣 - 特别是当你处理非技术上倾向的用户时,我曾经无数次。

+3

非常完整的答案;但我想补充一点:如果可能,请使用HTTPS/SSL。虽然在这里可能没有必要:有一些工具可以嗅探这样的“嘿,是否有更新?” - 问题和简单回答“是的,在这里,请拿我的代码并安装/执行它” '... – osti 2010-05-14 14:22:05

+3

甚至比使用SSL更好的是实际签署更新二进制文件并检查其签名。 SSL仅证明更新加载的URL是(任何)证书颁发给的。 为了完全保存,我将用我的公钥部署待更新的应用程序,使用我的私钥签署更新,然后检查更新本身。 – pilif 2010-06-25 08:39:32

0

实现此目的的最简单方法是使用类似libcurl的库来启动HTTP请求,并使其下载包含联机版本的ini或xml文件,并在其中提供新版本的联机版本。

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

+0

Qt有网络模块,因此可以在Qt中轻松处理HTTP请求,而无需使用额外的库。 – 2008-09-12 08:06:40

0

只需将最新版本的版本号以及从中下载新版本的URL放在服务器上的XML文件即可。然后您的应用程序可以请求XML文件,查看版本是否与自己的版本不同,并据此采取相应措施。

0

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

然后,您需要在您的服务器上只有一个ftp帐户,并且在构建新版本后可以通过ftp发送文件的构建系统。该构建系统甚至可以将安装文件/ zip直接放到您的网站上!

1

在服务器上,您只需要一个简单的文件“latestversion.txt”,其中包含最新版本的版本号(也可能是下载URL)。客户端只需要使用一个简单的HTTP请求(是的,到端口80)来读取这个文件来检索http://your.web.site/latestversion.txt,然后你可以解析它来获取版本号。这样你就不需要任何花哨的服务器代码---你只需要添加一个简单的文件到你现有的网站。

0

如果你想保持真正的基础,只需将一个version.txt上传到一个包含整数版本号的web服务器即可。将该检查下载到您下载的最新版本.txt,然后下载msi或安装程序包并运行它。

更高级的版本将使用RSS,XML或类似。最好使用第三方库来解析rss,如果你愿意的话,你可以包含显示给你的用户的信息。

基本上你只需要简单的下载功能。

这两种解决方案将只要求你从客户端访问端口80传出。这通常不需要对防火墙或网络进行任何更改(在客户端),并且您只需要面向互联网的Web服务器(虚拟主机,托管或您自己的服务器 - 所有这些都可以在此工作)。

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

21

Pilif回答是好,我有很多这方面的经验,但我却想添加更多的东西:

请记住,如果你开始yourapp.exe,那么“更新”将尝试用最新版本覆盖yourapp.exe。根据你的操作系统和编程环境(你提到的C++/QT,我没有这些经验),你会不是能够覆盖yourapp.exe,因为它会被使用。

我所做的是创建一个启动器。我有一个MyAppLauncher.exe,它使用配置文件(xml,非常简单)启动“真正的exe”。如果存在新版本,启动器可以更新“真正的exe”,因为它没有被使用,然后重新启动新版本。

只要记住这一点,你就会安全。

7

Martin,

你当然是绝对正确的。但我会用安装程序交付启动程序。或者只需下载安装程序,启动并尽快退出。原因是发射器中存在错误。你永远不会依赖于你不能更新的组件(或者忘记包含在最初的放置中)。

因此,我通过应用程序的更新过程分发的有效负载只是标准安装程序,但没有任何重要的用户界面。一旦客户端检查到安装程序有成功运行的机会,并且一旦它下载了更新程序,它就会运行并自行退出。

比运行更新,将其有效载荷安装到原始安装目录并重新启动(希望更新)的应用程序。

仍然:这个过程很毛茸茸,当您的应用程序具有广泛的使用焦点时,您最好在Windows平台上实现自动更新功能之前考虑两次。

+0

同意!我们不通过互联网更新。我们的“启动器”只启动一个进程,更新代码在应用程序中。在任何一种情况下,用户都不会自动执行此操作,我们通过VNC执行此操作,因为它是医疗数据库,并且我们不希望在有数据库脚本运行的情况下冒着数据库风险。良好 – 2008-09-11 14:12:41

2

我会同意@Martin和@ Pilif的回答,但加上;

考虑允许最终用户决定他们是否想要在那里实际安装更新,或者延迟安装更新直到他们完成使用该程序。

我不知道你的应用程序的目的/功能,但许多应用程序是在用户需要做某件特定的事情时启动的 - 没有什么比启动应用程序更烦人,然后被告知它被发现一个新版本,而你必须等待它下载,关闭应用程序并重新启动。如果您的程序有其他可能更新的资源(参考文件,数据库等),则问题会变得更糟。

我们有一个EPOS系统在大约400家商店中运行,最初我们认为让程序更新并下载它们(使用包含与上述建议非常相似的版本号的文件)会很好。 .. 好想法。直到所有的商店在大约同一时间(8:45-8:50am)启动他们的系统,并且我们的服务器被命中为20个Mb下载到400个远程服务器,然后更新本地软件并导致重新开始。混乱 - 没有人能够交易约10分钟。

不用说,这导致我们随后关闭“检查更新”功能并重新设计它,以允许商店“延迟”更新,直到当天晚些时候。 :-)

编辑:如果有任何人来自ADOBE正在阅读 - 为了上帝的缘故,为什么该死的acrobat读者坚持试图下载更新和废话时,我只是想开火阅读文档?开始时速度不够快,而且足够臃肿,没有浪费我生命中每20-30秒就要阅读一次PDF的每一次更新?
不要让他们使用他们自己的软件?? !!! :-)

2

如果您将文件保存在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"); 

这使你的网页浏览器认为它的下载应用程序

5
在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脚本可以返回来告诉客户端是否这是一个重要的,强制性的更新或不延长“协议”。

或者您可以添加一些文字以显示给用户 - 可能包含一些有关已更改内容的信息。

你的可能性是非常无限的。

4

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

相关问题