我知道这是一个老问题,但我想我会把我的解决方案放在这里,因为我正在做同样的事情。你的批处理想法是我的方式,但我所做的小改动是使用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
并让它在下次更新时被覆盖。但我没有在文件中注明删除它是安全的,以防以后有人查看它。