在Windows上自我更新Exe par

时间:2011-05-18 19:54:48

标签: windows perl par

我正在尝试创建一个在服务器上检测到新版本时会“自我更新”的脚本。最初的想法是,当检测到新版本时,下载文件,然后启动一个DOS批处理文件,只用新的文件覆盖原始的exe文件。我想,我可以使用sytem(启动update.bat)然后立即退出0; .bat文件等待几秒钟,然后尝试删除旧的exe。这个失败了,我猜是因为即使使用系统(启动...),新的“进程”实际上是同一个进程,这是正确的吗?有没有办法从Windows中的perl启动一个全新的进程,这将允许我删除.exe?或者有更好的方法吗?

谢谢, Eric Seifert

3 个答案:

答案 0 :(得分:2)

请参阅Windows Restart Manager上的文档,这是Windows Vista中引入的API,用于管理重新启动的应用程序以及更新。

答案 1 :(得分:1)

有没有听说过java WebStart? PAR等效,PAR :: WebStart 基本上,您配置它,然后从受信任的网站下载实时代码

所以你的.exe只是PAR :: WebStart的前端,真实的程序从你的网站上下载

答案 2 :(得分:1)

我知道这是一个古老的问题,但我想我会把解决方案放在这里,因为我正在研究同样的事情。您的批处理是我的方式,但我所做的微小改动是使用exec()而不是system(),因为前者(根据this)“...执行系统命令并且永不返回“,这似乎释放了正在运行的进程。当使用Strawberry Perl运行解释的Perl文件时,以及使用PAR::Packer运行已编译的程序时,这似乎都有效。

我创建了test.pl,最终编译为test.exe,如下所示:

#!/usr/bin/perl

use 5.10.0;
use strict;
use warnings;

    my $batch_file = <<"BATCH";
rem ### IT IS SAFE TO DELETE THIS FILE ###

\@echo off
ping 127.0.0.1 -n 2 -w 1000 > nul
echo Copying over update file...
copy testfile.exe test.exe

BATCH

    open my $fh, '>', 'update.bat';
    print $fh $batch_file;
    close $fh;

    exec( 'update.bat' );

testfile.exetest.exe的待机“升级”版本,只是为了确保我可以在test.exe运行时覆盖它,我可以。 ping是一种暂停2秒的方法,以确保在尝试覆盖文件之前进程有机会退出。

奇怪的是,创建的批处理文件update.bat无法自行删除,即使批处理文件通常可以自行删除。如果我创建一个批处理文件:

start /b "" cmd /c del %0

它会自行删除而不会出现任何错误。但是,如果我在update.bat中包含该代码段,则会抱怨The process cannot access the file because it is being used by another process.我不确定原因。由于这在我的应用中并不是特别重要,我没有追求这一点。我只是留下update.bat,并在下次更新时将其覆盖。但是我在文件中注明,如果有人在以后查看它,可以安全删除。