2

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

谢谢,埃里克塞弗特

4

3 回答 3

2

请参阅有关 Windows重新启动管理器的文档,这是一种随 Windows Vista 引入的 API,用于为您管理重新启动的应用程序以获取更新。

于 2011-05-18T20:25:16.190 回答
1

听说过 java WebStart 吗?有一个 PAR 等效项 PAR::WebStart 基本上,您对其进行配置,然后从受信任的网站实时下载代码

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

于 2011-08-13T19:43:54.427 回答
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.exe是 的备用“升级”版本test.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并让它在下次更新时被覆盖。但我没有在文件中注明删除它是安全的,以防以后有人查看它。

于 2015-05-23T21:49:45.757 回答