2017-03-17 4 views
1

Ich bin auf der Suche nach einer Möglichkeit für eine Batch-Datei, um nach der Ausführung an einen bekannten Speicherort verschoben werden. Selbstbewegend - schien der passendste Name zu sein, aber ich bin mir sicher, dass es einen technischen Ausdruck dafür gibt. Ich möchte die Batch-Datei nach den ganzen anderen Code ausgeführt haben.Self-moving Batch-Datei

move "C:\temp\move_me.bat" "D:\temp\move_me.bat" 

Wo move_me.bat die gleichnamige Batch-Datei in c gesetzt ist: \ temp bis d bewegen: \ temp.

Ich erhalte den Fehler

The batch file cannot be found.

Auch wenn die Batch-Datei Speicherort verschoben. Ich bin ein bisschen verwirrt. Muss ich den Fehler unterdrücken oder wäre es am besten, die Batch-Datei zu kopieren und die Quelle zu löschen? Oder gibt es einen besseren Weg, dies zu tun?

Antwort

3

die Windows-Eingabeaufforderung cmd nicht Cache-Batch-Dateien im Speicher, liest sie aus der Datei Zeile für Zeile . Daher erhalten Sie einen Fehler, sobald der Befehl move beendet ist, weil die Datei nicht mehr gefunden werden kann.

Sie können die Batch-Datei wie folgt aufrufen, den Fehler zu unterdrücken:

Nachrichten
"C:\temp\move_me.bat" 2> nul 

Aber diese unterdrückt alle anderen Fehler auch unbeabsichtigt.

Wie auch immer, vielleicht der folgende Ansatz funktioniert für Sie - das ist das Skript C:\temp\move_me.bat:

if /I "%~dp0"=="D:\temp\" exit /B 
rem // (some other code here...) 
copy "%~f0" "D:\temp\%~nx0" 
"D:\temp\%~nx0" & del "%~f0" 

Zunächst wird die Lage der aktuell laufen Batch-Datei gegen D:\temp\ geprüft wird; Wenn es gleich ist, wird die Batch-Datei sofort beendet.

schließlich die ursprüngliche Batchdatei (Zugriff durch %~f0) kopiert wird (nicht verschoben) an den neuen Standort D:\temp (Dateinamen, %~nx0, gleich bleibt).

Die nächste Zeile führt die Batch-Datei von der neuen Position, aber ohne call, die benötigt wird, um an das aufrufende Batch-Skript zurückzukehren, aber das ist nicht was wir wollen.Die & operator lässt den nächsten Befehl ausführen, wenn der vorherige beendet ist. Obwohl call nicht verwendet wird, wird der nächste Befehl weiterhin ausgeführt, da die gesamte Zeile bereits von cmd gelesen und analysiert wurde. Die Ausführungssteuerung befindet sich jetzt jedoch in der neuen Instanz der Stapeldatei, sodass die Fehlermeldung The batch file cannot be found. nicht mehr angezeigt wird.

Die zuvor erwähnte if Abfrage beendet die Ausführung der Kopie der Stapeldatei sofort, so dass der andere Code nicht zweimal ausgeführt wird.

Falls Sie nicht wollen, um die Ausführung der kopierten Batch-Datei überspringen, entfernen Sie die if Befehlszeile und ändern Sie die copy Befehlszeile dieses zu erhalten:

rem // (some other code here...) 
copy "%~f0" "D:\temp\%~nx0" > nul || exit /B 
"D:\temp\%~nx0" & del "%~f0" 

Die > nul portion Displaymeldungen unterdrückt (einschließlich der Zusammenfassung 1 file(s) copied.). Der || operator führt den nächsten Befehl nur aus, wenn der Kopiervorgang fehlschlägt. Wenn die ursprüngliche Stapeldatei ausgeführt wird, wird das Kopieren wie erwartet ausgeführt. Wenn die kopierten Batch-Datei ausgeführt wird, copy versucht die Batch-Datei auf sich selbst zu kopieren, die in der Nachricht führt The file cannot be copied onto itself. (unterdrückt durch > nul) und in einem Fehler, der den exit /B Befehl (wegen ||) feuert die Batch-Datei zu verlassen, so dass die Die letzte Zeile wird nicht ausgeführt.


Sie können das gleiche Verhalten auch mit move erreichen; so dass der zugehörige Code sieht wie folgt aus:

if /I "%~dp0"=="D:\temp\" exit /B 
rem // (some other code here...) 
move "%~f0" "D:\temp\%~nx0" & "D:\temp\%~nx0" 

Oder, wenn Sie die anderen Code wollen nicht für das bewegte Skript übersprungen werden:

rem // (some other code here...) 
if /I not "%~dp0"=="D:\temp\" move "%~f0" "D:\temp\%~nx0" & "D:\temp\%~nx0" 

Die if Abfrage ist notwendig, da move, im Gegensatz zu copy, gibt keinen Fehler zurück, wenn Quelle und Ziel identisch sind.

Hier ist eine umfassende Lösung für eine Batch-Datei, die sich selbst bewegt und die Kontrolle über die bewegte nachher gibt. Werfen Sie einen Blick auf all die Erläuterungen, um herauszufinden, welcher Code durch welche Batch-Datei-Instanz ausgeführt wird:

@echo off 

rem // Define constants here: 
set "_TARGET=D:%~pnx0" & rem /* (this defines the movement destination; 
         rem  in your situation, the original batch file is 
         rem  `C:\temp\move_me.bat`, so the target file is 
         rem  `D:\temp\move_me.bat` (only drive changes)) */ 

rem // (code that runs for both batch file instances...) 
echo Batch file: "%~f0" 
echo [executed by both files before the movement check] 

rem // Check whether current batch file is the moved one: 
if /I "%~f0"=="%_TARGET%" (

    rem // (code that runs for the moved batch file instance only...) 
    echo Batch file: "%~f0" 
    echo [executed only by the moved file] 

) else (

    rem // (code than runs for the original batch file instance only...) 
    echo Batch file: "%~f0" 
    echo [executed only by the original file] 

    rem // Actually move the batch file here, then give control to the moved one: 
    > nul move "%~f0" "%_TARGET%" 
    "%_TARGET%" 

    rem /* (code that runs for the original batch file instance only; 
    rem  this is run after the moved batch file has finished; 
    rem  you must not use `goto` herein as the target label cannot be found, 
    rem  because the original file does no longer exist at this point!) */ 
    echo Batch file: "%~f0" 
    echo [executed only by the original file, but after the moved one has finished] 

) 

rem // (code that runs for the moved batch file instance only...) 
echo Batch file: "%~f0" 
echo [executed only by the moved file after the movement check] 

exit /B 

1) Beachten Sie, dass Codeblöcke parenthesised (/) und weiterhin Linien ^ gelten als eine einzige Befehlszeile: Hinweis

(
    echo This entire parenthesised block is 
    echo considered as a single command line. 
) 
echo This continued line &^
echo as well.

2), dass solche Argument Referenzen werden sofort, sobald eine Befehlszeile o aufgelöst r Block wird gelesen und geparst, also bevor es tatsächlich ausgeführt wird.

0

Batch-Dateien werden Zeile für Zeile ausgeführt, anstatt sie in einem Durchgang in den Speicher einzulesen. Haben Sie weitere Befehle nach dem Befehl move?

Batch-Dateien haben jedoch auch die Funktion, dass das Aufrufen einer anderen Batch-Datei Ihre Batch-Datei überlagert.

Also, Sie könnte der Lage sein, mit wegzukommen:

if "%1" == "continuation" goto :continuation 

REM interesting things go here 

move "C:\Temp\move_me.bat" "D:\Temp\move_me.bat" 
"D:\Temp\move_me.bat" continuation 

:continuation 
REM more interesting things go here 

Alternativ Kopie Ihre Batch-Datei zum Ziel und haben die Fortsetzung der Originalkopie löschen.

Oder haben Sie Ihre Batch-Datei selbst zum Ziel kopieren (und löschen Sie sich selbst) als ersten, was es tut. Das könnte leichter zu verstehen sein.

+0

Die Zeile nach 'move' wird nicht mehr erkannt, denke ich. Vielleicht könnten Sie 'move' in' copy' ändern und die ursprüngliche Batch-Datei mit 'del' im': continuation'-Abschnitt löschen ... – aschipfl

+0

... oder 'move' behalten, aber einfach die nächste Zeile mit' & 'verketten dann sollte es erkannt werden ... – aschipfl

Verwandte Themen