red-eye
Goto Top

Mit Robocopy aus Batchdatei werden neuerdings Laufwerkfehler angezeigt - warum?

Hallo Administrator.de-Mitglieder,

bislang hatte ich mit zwei Batch-Dateien mit dem Befehl Robocopy ein wichtiges Verzeichnis auf meiner Festplatte mit einem Netzwerkverzeichnis oder mit einem USB-Stick synchronisiert.

Als ich mir vor drei Wochen mit dem brandneuen und noch fehlerhaften Kaspersky 2014 meine Userrechte zerschossen hatte, setzte ich mein Notebook Dell Vostro 3450 (14''-Bildschirm) mit 64-bit und Windows 7 Professional vollkommen neu auf. In den Explorer-Ordneroptionen deaktiviere ich neuerdings das Häkchen für "Leere Laufwerke im Ordner Computer ausblenden. Ich lasse im Navigationsbereich "Alle Ordner anzeigen" und "Automatisch auf aktuellen Ordner erweitern".

Seitdem zeigt mir meine Synchronisations-Batch eine von cmd/win ausgehende Fehlermeldung an:
ad9a7b093030d2350bc0c5f0346e6075

Der folgende Code entspricht der Synchronisation der neueren Dateien von USB-Stick zur Festplatte:
:: Überprüfung der Verzeichnisse
if exist E:\autorun.inf (set source="E:\ME" & goto var_chk) else (set source=0)  
if exist F:\autorun.inf (set source="G:\ME" & goto var_chk) else (set source=0)  
if exist "C:\Users\USER\Documents\ME" (  
  set destin="C:\Users\USER\Documents\ME"  
  ) else (set destin=0)
:var_chk
if not %source%==0 (goto src_ok) else (goto src_fe)
:src_ok
if not %destin%==0 (goto s_d_ok) else (goto dst_fe)
:src_fe
if not %destin%==0 (goto dst_ok) else (goto s_d_fe)
:s_d_ok
goto rbc_show
:dst_fe
echo Ziel nicht vorhanden: Stick nicht eingesteckt oder nicht erkannt!
goto fehler
:dst_ok
echo Quelle nicht vorhanden: Vermutlich falsches Synchronisationsprogramm!
goto fehler
:s_d_fe
echo Quelle und Ziel nicht vorhanden: Vermutlich falsches Synchronisationsprogramm!
goto fehler

:: Robocopy listet zuerst Unterschiede der Verzeichnisse auf
:rbc_show
choice /c jn /t 90 /d n /m "M”chten Sie eine Liste der Unterschiede erhalten? "  
if errorlevel 255 goto fehler
if errorlevel 2 goto wahl_syn
if errorlevel 1 goto robo_lst
if errorlevel 0 goto wahl_syn
goto fehler
:robo_lst
robocopy %source% %destin% /mir /xo /fft /r:3 /w:10 /l
pause

:: Synchronicity fragt ab, ob die Synchronisation erfolgen soll
:wahl_syn
choice /c jn /t 90 /d n /m "Soll nun eine Synchronisation durchgefhrt werden? "  
if errorlevel 255 goto fehler
if errorlevel 2 goto abbruch
if errorlevel 1 goto wahl_del
if errorlevel 0 goto abbruch
goto fehler

:: Synchronicity fragt, ob die *Extra Dateien auf dem Ziellaufwerk erhalten werden sollen
:wahl_del
choice /c jn /t 90 /d j /m "Wollen Sie in Quelle gel”schte Dateien in Ziel behalten? "  
if errorlevel 255 goto fehler
if errorlevel 2 goto start_dl
if errorlevel 1 goto start_kp
if errorlevel 0 goto abbruch
goto fehler

:: Robocopy kopiert ohne Löschen der *Extra Dateien im Ziellaufwerk
:start_kp
robocopy %source% %destin% /e /xo /fft /r:3 /w:10
goto ende

:: Robocopy kopiert und löscht *Extra Dateien im Ziellaufwerk
:start_dl
robocopy %source% %destin% /mir /xo /fft /r:3 /w:10
goto ende

:: Ende-Prozeduren
:abbruch
echo Synchronisation abgebrochen
goto ende_
:fehler
echo Synchronisation wegen eines Fehlers nicht gestartet, Programm beendet.
goto ende_
:ende
echo Synchronicity erfolgreich beendet.
:ende_
pause
Ich konnte das Problem jetzt umgehen, indem ich die Laufwerke der Sticks einen Buchstaben hochsetzte. Aber falls die Frage nicht zu trivial ist, oder zu umständlich: Kann mir jemand die Fehlermeldung erklären? Kann ich E: trotzdem durchsuchen lassen, falls mal die Laufwerke anders sortiert oder ein Laufwerk von Windows ausgelassen wird?

Vielen Dank im Voraus fürs Lesen und für jeden Beitrag!

Gruß,
red-eye

Content-Key: 218779

Url: https://administrator.de/contentid/218779

Ausgedruckt am: 29.03.2024 um 13:03 Uhr

Mitglied: Endoro
Endoro 08.10.2013 um 16:50:06 Uhr
Goto Top
Hi, ich nehme an, du suchst den Laufwerksbuchstaben für den Stick?
Das könnte so gehen:
for /f "tokens=2delims==" %%a in ('wmic volume where "drivetype=2" get name /format:list^|find "="') do set "source=%%a"  
echo %source%
lg.
Mitglied: red-eye
red-eye 08.10.2013 aktualisiert um 20:06:22 Uhr
Goto Top
Hallo Endoro!

Ja, im Grunde ist es das. Vielen Dank für Deinen interessanten Code! Könntest Du mir noch ein wenig detaillierter erklären, was Dein komplizierter Befehl alles beinhaltet?

- Was bedeutet "tokens=2delims==", was "%%a", was ist "'wmic volume where "drivetype=2" get name"?
- Was sind das für interessante Formatierungsbefehle: "/format:list^|find "=""?

Schau mal, das Problem bleibt dasselbe! E: ist bei mir offensichtlich ein SD-Karten-Laufwerk, derzeit leer. G: (Verbatim) ist der Stick.
6782aeb340d9528807451b028715b159
b37241442a383ebcd583e3136e384cc1

Mit freundlichen Grüßen,
red-eye
Mitglied: pieh-ejdsch
pieh-ejdsch 08.10.2013 aktualisiert um 21:21:59 Uhr
Goto Top
Moin red-eye,

Die Fehler-MessageBox erscheint, weil der Befehlsinterpreter vor dem Zugriff auf das Laufwerk nicht auf ein Vorhandenes gültiges eingebundenes Medium (Volume) prüft.
Eine ExistensPrüfung mit if grätscht da leider genauso wie die Erweiterungen von ForVariablen und Batchparametern.
Eine Prüfung auf ein eingebundenes Medium (E: ) erfolgt in der CMD-Line mit
vol E: >nul 2>nul && echo Laufwerk E: ist online

for /f "delims=\ " %v in ('mountvol ^|find ":\"^|sort') do @vol %v >nul 2>nul&&echo Laufwerk %v mit Medium
Oder, was in Deinem Fall mit DIR direkt mit Autorun.inf
dir E:\autorun.inf >nul &&echo USB Stick ist E:

for /f "tokens=2delims==\" %v in ('wmic volume where "drivetype=2" get name /format:list^|find "="') do @dir %v\Autoupdateslog.txt >nul 2>nul &&echo USB Stick ist %v

Warum machst Du diese Überprüfungen am Anfang nur halb und doppelt? Etwas chronologisch wäre es in etwa so:
:: Überprüfung der Verzeichnisse
 rem etwas einfacher Gestaltet
set "source="  
set "destin="  
set "USBpaht="  
for /f "tokens=2delims==\" %%v in ('wmic volume where "drivetype=2" get name /format:list^|find "="') do vol %v >nul 2>nul &&call set "USBpaht=%%USBpath%%%v\;"  
 rem Suche nach autorun.inf
for %%i in (autorun.inf) do (
 if %%~d$USBpath:i equ E: set source="%%~d$USBpath:i\ME"  
 rem warum hier eigentlich LW G:?
 if %%~d$USBpath:i equ F: set source="G:\ME"  
)
if exist "C:\Users\USER\Documents\ME" set destin="C:\Users\USER\Documents\ME"  
 rem prüfe parameter var_chk
if not defined source if not defined destin (goto s_d_fe) else goto s_fe
if defined destin goto rbc_show
 rem :dst_fe
echo Ziel nicht vorhanden: Stick nicht eingesteckt oder nicht erkannt!
goto fehler
:s_fe
echo Quelle nicht vorhanden: Vermutlich falsches Synchronisationsprogramm!
goto fehler
:s_d_fe
echo Quelle und Ziel nicht vorhanden: Vermutlich falsches Synchronisationsprogramm!
goto fehler

:: Robocopy listet zuerst Unterschiede der Verzeichnisse auf
:rbc_show
 rem hier gehts weiter

Gruß Phil
Mitglied: red-eye
red-eye 08.10.2013 um 21:59:59 Uhr
Goto Top
Hi Phil,
vielen Dank schon Mal! Ich werde mir das in Ruhe alles ansehen und testen!
face-smile
Gruß, red-eye
Mitglied: Endoro
Endoro 09.10.2013 um 01:14:43 Uhr
Goto Top
Hi,
man kann- mit ordentlichem Aufwand- Windows überreden, ausgehend von "Verbatim" das logische Laufwerk auszugeben:
@ECHO OFF &SETLOCAL
for /f "delims=" %%a in ('wmic path win32_diskdrive where 'model like "%%Verbatim%%"' get deviceid /value') do (  
	for /f "tokens=2delims==" %%b in ("%%~a") do set "diskdrive=%%b"  
)
for /f tokens^=7delims^=^" %%a in ('wmic path win32_diskdrivetodiskpartition get /FORMAT:CSV ^| FIND "%diskdrive%"') do set "partition=%%a"  
for /f tokens^=7delims^=^" %%a in ('wmic path win32_logicaldisktopartition get /FORMAT:CSV ^| FIND "%partition%"') do set "drive=%%a"  
echo %drive%
Wenn mehrere Verbatim-Laufwerke angeschlossen sind, würde ich über label eindeutige Namen vergeben und die mit vol abfragen.
lg.
Mitglied: red-eye
red-eye 09.10.2013 aktualisiert um 02:17:21 Uhr
Goto Top
Hallo Endoro, hallo Phil!

Endoro, vielen Dank für Deine neuen Ideen! Ich bin allerdings noch zu Fuß dabei, Deine und Phils Code-Vorschläge zu verstehen. Bin leider nicht ganz so firm, wie Ihr Experten. Könntest Du mir dabei nochmals helfen?

- Warum wählst Du tokens^=7
- Ich verstehe einfach nicht, was ein Token ist ...
- Was sind in der Hilfe für FOR eigentlich die umgekehrten Anführungszeichen und Anführungszeichen?


Ich möchte nun gerne noch wiedergeben, was ein Test Eurer Vorschläge für die Laufwerkerkennung ergab:

1. Endoros erster Vorschlag:
C:\Windows\system32>for /F "tokens=2delims==" %a in ('wmic volume where "drivetype=2" get name /format:list|find "="') do set "source=%a"  
" \Windows\system32>set "source=G:\  
" \Windows\system32>set "source=E:\  

C:\Windows\system32>echo Source ist E:\
Source ist E:\

C:\Windows\system32>if exist E:\autorun.inf (echo Source ist E:\ und ist Stick) else (if not exist E:\autorun.inf echo Source ist E:\, aber nicht Stick ...)
Source ist E:\, aber nicht Stick ...
2. Phils Vorschlag:
C:\Windows\system32>set source=   && set destin=   && set usbpath=   && echo Source , Destin , USB-Path
Source , Destin , USB-Path

C:\Windows\system32>for /F "tokens=2delims==\" %v in ('wmic volume where "drivetype=2" get name /format:list|find "="') do vol  %v\;"  

C:\Windows\system32>vol  G:\;"  

Das System kann das angegebene Laufwerk nicht finden.
Folgender Fehler trat auf: G:\.
Volume in Laufwerk C: hat keine Bezeichnung.
Volumeseriennummer: 1C5B-5695

C:\Windows\system32>vol  E:\;"  

Das System kann das angegebene Laufwerk nicht finden.
Folgender Fehler trat auf: E:\.
Volume in Laufwerk C: hat keine Bezeichnung.
Volumeseriennummer: 1C5B-5695

C:\Windows\system32>echo Source  , Destin  , USB-Path
Source  , Destin  , USB-Path
Es gibt offenbar mehrere Wege, ein Laufwerk, bzw. einen USB-Stick am USB-Anschluß zu erkennen. Meiner lief ursprünglich darauf hinaus, dasjenige Laufwerk als USB-Stick zu definieren, welches eine Datei autorun.inf im Stammverzeichnis enthält. Bei der Suche danach trat aber wegen des leeren, dennoch vorhandenen SD-Karten-Verzeichnisses die oben dargestellte Fehlermeldung auf.

Wenn ich Euch richtig verstehe, dann sucht Ihr mit einem Systembefehl nach vorhandenen Laufwerken, in der Hoffnung, daß die Fehlermeldung nicht aufkommt. Bei Endoros erstem Lösungsversuch geschah das leider trotzdem. Bei Phils Vorschlag entsteht leider ein anderer Fehler. Endoros zweiter Vorschlag könnte scheitern, sobald ich einmal einen anderen als den Verbatim-Stick verwenden würde. Dennoch vielen Dank für Eure interessanten Code-Stücke, aus denen ich wieder eine Menge lernen und nachmachen kann!

Eine Lösung könnte der Code mit der Laufwerkssuche mit vol >nul darstellen. Er erzeugt diese oben dargestellte Messagebox nicht. Aber auch dazu wieder eine Frage:

- Was bedeutet dieser Befehl?
- Und vor allem, was bedeutet >nul, und wozu noch 2>nul?


Bitte seid so freundlich, und geht ersteinmal noch auf meine Fragen ein, bevor Ihr die nächsten brillianten Codes vorschlagt, die ich aber nicht richtig verstehen kann!

Herzliche und dankbare Grüße von
Red-eye
Mitglied: red-eye
red-eye 09.10.2013 aktualisiert um 04:01:02 Uhr
Goto Top
Zuletzt noch der Test mit dem Befehl mit vol und >nul, der USB-Stick ist an Laufwerk G:.

Code:
set hdpath= && set usbpath= && set usbdrive= && set source= && set destin=
set hdpath=\Users\USER\Documents\ME
set usbpath=\ME
vol E: >nul 2>nul && set usbdrive=E:
vol F: >nul 2>nul && set usbdrive=F:
vol G: >nul 2>nul && set usbdrive=G:
vol H: >nul 2>nul && set usbdrive=H:
vol I: >nul 2>nul && set usbdrive=I:
vol J: >nul 2>nul && set usbdrive=J:
if exist %usbdrive%\autorun.inf (set source=%usbdrive%%usbpath%) else (set source=0)
echo Source ist %source%
Ergebnis:
C:\Windows\system32>set hdpath=   && set usbpath=   && set usbdrive=   && set source=   && set destin=
C:\Windows\system32>set hdpath=\Users\USER\Documents\ME
C:\Windows\system32>set usbpath=\ME
C:\Windows\system32>vol E:   1>nul 2>nul  && set usbdrive=E:
C:\Windows\system32>vol F:   1>nul 2>nul  && set usbdrive=F:
C:\Windows\system32>vol G:   1>nul 2>nul  && set usbdrive=G:
C:\Windows\system32>vol H:   1>nul 2>nul  && set usbdrive=H:
C:\Windows\system32>vol I:   1>nul 2>nul  && set usbdrive=I:
C:\Windows\system32>vol J:   1>nul 2>nul  && set usbdrive=J:
C:\Windows\system32>if exist G:\autorun.inf (set source=G:\ME )  else (set source=0 )
C:\Windows\system32>echo Source ist G:\ME
Source ist G:\ME
Mitglied: pieh-ejdsch
pieh-ejdsch 09.10.2013, aktualisiert am 10.10.2013 um 09:41:12 Uhr
Goto Top
Moin red-eye,
Wenn ich Euch richtig verstehe, dann sucht Ihr mit einem Systembefehl nach vorhandenen Laufwerken, in der Hoffnung, daß die Fehlermeldung nicht aufkommt. Bei Endoros erstem Lösungsversuch geschah das leider trotzdem. Bei Phils Vorschlag entsteht leider ein anderer Fehler.
Nein - der Befehl vol oder der Befehl dir verhindern das Auftreten der Fehlermeldung mittels Messagebox, was aber mit der Standardfehlerausgabe (Handle 2) der CMD-Line nichts zu tun hat.

mountvol listet nur die lokal eingebundenen Laufwerke auf, wmic nur die USB Laufwerke, anstatt eine Liste von A-Z durchzugehen wird schon ausgefiltert.
Dein Test in Zeile 4
C:\Windows\system32>for /F "tokens=2delims==\" %v in ('wmic volume where "drivetype=2" get name /format:list|find "="') do vol  %v\;"   
hast Du etwas falsch übernommen ->> copy paste Fehler?
for /f "tokens=2delims==\" %%v in ('wmic volume where "drivetype=2" get name /format:list^|find "="') do vol %v >nul 2>nul &&call set "USBpaht=%%USBpath%%%v\;"  
Es sollte sicher so aussehen:
for /f "tokens=2delims==\" %%v in ('wmic volume where "drivetype=2" get name /format:list^|find "="') do vol %v  
Die Ausgabe des Verwaltungintrumentes (wmic) wird in der Forschleife mit "tokens=2" dazu angewisen das zweite vorkommen inerhalb des/der delimiter(s) "=\" "delims==\" in der Variable %v auszugeben.
Der Befehl Vol erwartet nur eine Laufwerksbezeichnung gefolgt von einen Doppelpunkt, sonst nichts. wird etwas anderes Hinzugefügt interpretiert die CommanLine dies als keine Eingabe, da diese Syntax nicht erwartet wird. Also wird laut vol /? das Aktuelle Laufwerk angezeigt.

Theoretisch würde es auch so etwas umständlich wen der VolumeName des Laufwerkes VERBATIM16 ist, gehen:
for %L in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do vol %L: 2>nul |findstr /ec": ist VERBATIM16" >nul &&set "LW=%L:"  
In einer Autorun.inf kannst Du auch noch ganz speziell ein Label vergeben und nach einer gewissen Zeichenfolge suchen. Der Möglichkeiten gibt es noch viele mehr
um einen Bestimmten Datenträger ausfindig zu machen; siehe: @Endoro

So ganz nebenbei: Von wo aus wird denn das Backkup angestossen?

@Friemler hat unter Wissen ein schönes For-Tutorial verfasst.
vol D: >nul 2>nul &&echo Laufwerk D: ist vorhanden ||echo Laufwerk D: ist ohne Medium

In der Befehlszeilenreferenz kannst Du Dir die Erklärungen genauer durchlesen.

Gruß Phil
Mitglied: red-eye
red-eye 09.10.2013 um 22:29:14 Uhr
Goto Top
Hallo Phil,

vielen Dank für Deine erneute Antwort und für die vielen Erklärungen! Ich lese so nach und nach in der Wissenswelt bei Administrator.de, insbesondere gehe ich Deinen Empfehlungen zur Erklärung der FOR-Schleife nach. (Ist allerdings viel Lese- und Versteh-Stoff, ich bin noch lange nicht durch.)

Zitat
Dein Test in Zeile 4 ... hast Du etwas falsch übernommen ->> copy paste Fehler?
Das ist gut möglich, da ich mich mit der Syntax dieser komplizierten Befehle überhaupt nicht auskenne. Ich habe nun also, ohne wirklich zu wissen, welche Zeichen nötig sind, anhand der von cmd.exe ausgelieferten Ergebnisse etwas experimentiert.

Mit Endoros Vorschlag werden die Laufwerke durchgetestet. Probleme bei seinem Vorschlag waren, daß der Backslash mitgeliefert wurde, und daß die Laufwerke zwar gefunden, aber nicht überprüft wurden. Den Backslash habe ich entfernt, damit entsteht folgendes Ergebnis:
C:\Windows\system32>set hdpath= && set usbpath= && set usbdrive= && set source= && set destin=
C:\Windows\system32>set hdpath=\Users\USER\Documents\ME && set usbpath=\ME
C:\Windows\system32>for /F "tokens=2delims==\" %a in ('wmic volume where "drivetype=2" get name /format:list|find "="') do set usbdrive=%a  
C:\Windows\system32>set usbdrive=G:
C:\Windows\system32>set usbdrive=F:
C:\Windows\system32>set usbdrive=E:
C:\Windows\system32>if exist E:\autorun.inf (set source=E:\ME ) else (set source=0 )
C:\Windows\system32>echo Source 0
Source 0
Dann der Vorschlag von Phil, ich habe ihn jetzt durch einiges Ausprobieren korrigiert. Er zählt die Laufwerke rückwärts durch, überprüft sie und findet das kleinste aktive Laufwerk. Durch die Übergabe des Fehlercodes an nul bleibt nun auch die ursprüngliche störende Fehler-Messagebox aus:
C:\Windows\system32>set hdpath= && set usbpath= && set usbdrive= && set source= && set destin=
C:\Windows\system32>set hdpath=\Users\USER\Documents\ME && set usbpath=\ME
C:\Windows\system32>for /F "tokens=2delims==\" %v in ('wmic volume where "drivetype=2" get name /format:list|find "="') do vol %v 1>nul 2>nul && set usbdrive=%v  
C:\Windows\system32>vol G: 1>nul 2>nul && set usbdrive=G:
C:\Windows\system32>vol F: 1>nul 2>nul && set usbdrive=F:
C:\Windows\system32>vol E: 1>nul 2>nul && set usbdrive=E:
C:\Windows\system32>if exist F:\autorun.inf (set source=F:\ME ) else (set source=0 )
C:\Windows\system32>echo Source F:\ME
Source F:\ME
Der entscheidende Punkt, der meine Synchronisations-Batch nun wieder funktionstüchtig macht, ist tatsächlich die Ermittlung des Laufwerks mit Übergabe des Fehlers (Handle 2) an nul. Hiermit kann ich dann sogar auch mit meinen etwas einfacheren Bordmitteln die Laufwerke rückwärts zählen und das unterste aktive Laufwerk ermitteln. Ich habe ja insgesamt vier USB-Buchsen, theoretisch könnten sie alle belegt sein, aber sinnvoll ist die Auswahl des untersten aktiven USB-Laufwerks. Offenbar zählt der Befehl vol das CD-Laufwerk und die Festplatte nicht mit. Dann entsteht folgender Code:
C:\Windows\system32>set hdpath= && set usbpath= && set usbdrive= && set source= && set destin=
C:\Windows\system32>set hdpath=\Users\USER\Documents\ME && set usbpath=\ME
C:\Windows\system32>vol J: 1>nul 2>nul && set usbdrive=J: && vol I: 1>nul 2>nul && set usbdrive=I: && vol H: 1>nul 2>nul && set usbdrive=H:
C:\Windows\system32>vol G: 1>nul 2>nul && set usbdrive=G: && vol F: 1>nul 2>nul && set usbdrive=F: && vol E: 1>nul 2>nul && set usbdrive=E:
C:\Windows\system32>if exist F:\autorun.inf (set source=F:\ME ) else (set source=0 )
C:\Windows\system32>echo Source F:\ME
Source F:\ME
Ich denke, damit sind mein Problem gelöst und meine Frage nach den Ursachen beantwortet. Ich werde die Frage als gelöst setzen.

Vielen Dank an Endoro und Phil! face-smile
red-eye