2011-05-18 4 views
2

J'essaye de créer un script qui "s'actualisera" quand il détectera une nouvelle version sur un serveur. Initialement, l'idée que j'avais était, quand une nouvelle version est détectée, télécharger le fichier, puis démarre un fichier batch DOS qui écrase simplement l'exe original avec le nouveau. J'ai pensé, que je pourrais utiliser sytem (démarrer update.bat) puis immédiatement quitter 0; Le fichier .bat attend pendant quelques secondes, puis essaie de supprimer l'ancien exe. Cela échoue, je suppose que même lorsque vous utilisez le système (démarrer ...), le nouveau "processus" est en fait le même processus, est-ce correct? Est-il possible de lancer un processus complètement nouveau à partir de Perl dans Windows, ce qui me permettrait de supprimer le fichier .exe? Ou y a-t-il une approche différente qui serait meilleure?Mise à jour automatique Exe par sur Windows

Merci, Eric Seifert

Répondre

2

Voir la documentation sur Windows Restart Manager, une API introduite avec Windows Vista qui gère le redémarrage des applications, mises à jour, pour vous.

+0

Malheureusement, il s'agit d'un environnement XP que j'ai à traiter ... Mais cela ressemble à ce que je voudrais. –

+1

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 –

+0

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. –

1

Vous avez déjà entendu parler de Java WebStart? PAR: WebStart Fondamentalement, vous le configurez, puis téléchargez le code en direct à partir d'un site Web de confiance

ainsi votre .exe serait juste une interface vers PAR :: WebStart, avec le vrai programme téléchargé hors Votre site Web

1

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.