Je sais que c'est une vieille question, mais j'ai pensé que je mettrais ma solution ici puisque je travaille sur le même genre de chose. Votre idée de lot est la façon dont je suis allé, mais le petit changement que j'ai fait était d'utiliser exec()
au lieu de system()
puisque le premier (selon this) "... exécute une commande système et ne retourne jamais", ce qui semble libérer le processus en cours. Cela semble fonctionner à la fois lors de l'exécution de fichiers Perl interprétés avec Strawberry Perl et lors de l'exécution de programmes compilés avec PAR::Packer
.
J'ai créé test.pl
, qui a finalement été compilé à test.exe
, comme suit:
#!/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
est une attente « mise à niveau » version de test.exe
, juste pour vous assurer que je peux écraser test.exe
alors qu'il est en cours d'exécution , et je peux. Le ping
est un moyen de faire une pause de 2 secondes pour s'assurer que le processus a eu une chance de quitter avant d'essayer d'écraser le fichier. Bizarrement, le fichier de traitement par lots créé update.bat
ne peut pas se supprimer lui-même, même si les fichiers de traitement par lots peuvent normalement se supprimer eux-mêmes. Si je crée un fichier de commandes avec ceci:
start /b "" cmd /c del %0
Il va se supprimer sans aucune erreur. Mais si j'inclus cet extrait dans update.bat
, il se plaint que The process cannot access the file because it is being used by another process.
je ne sais pas pourquoi. Puisque ce n'est pas particulièrement important dans ma demande, je n'ai pas poursuivi cela. Je laisse simplement update.bat
derrière moi et je le laisse être écrasé la prochaine fois qu'une mise à jour se produit. Mais je note dans le fichier qu'il est sûr de supprimer au cas où quelqu'un le regarderait plus tard.
Malheureusement, il s'agit d'un environnement XP que j'ai à traiter ... Mais cela ressemble à ce que je voudrais. –
Si vous ne pouvez pas utiliser le Gestionnaire de redémarrage, il existe de nombreuses techniques hacky pour les exécutables auto-effaçables. http://catch22.net/tuts/selfdel –
Merci Adrian, cet article a mentionné la technique exacte que j'ai décrite ci-dessus, en utilisant le fichier batch. L'utilisation de la commande ShellExecute de Win32 :: FileOp m'a permis de l'exécuter comme je le voulais. –