私はこれが古い質問であることを知っていますが、私は同じ種類のことに取り組んでいるので、ここに私の解決策を置くと思いました. あなたのバッチのアイデアは私が行った方法ですが、私が行った小さな変更は、前者(thisによると)「...システムコマンドを実行し、決して返さない」ため、実行中のプロセスを解放するように見えるexec()
代わりに使用することでした。これは、解釈された Perl ファイルを Strawberry Perl で実行する場合と、コンパイルされたプログラムを で実行する場合の両方で機能するようです。system()
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
にして、次に更新が発生したときに上書きされるようにします。ただし、後で誰かが見た場合に備えて、削除しても安全であることをファイルに記録しています。