Zunächst lassen Sie mich sorgen Sie für eine schnelle und schmutzige Korrektur Ihres Codes; Erklärungen folgen unten:
@echo off
> "zip.vbs" echo('Get command-line arguments.
>>"zip.vbs" echo(Set objArgs = WScript.Arguments
>>"zip.vbs" echo(InputFolder = objArgs(0)
>>"zip.vbs" echo(ZipFile = objArgs(1)
>>"zip.vbs" echo(
>>"zip.vbs" echo('Create empty ZIP file.
>>"zip.vbs" echo(CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar)
>>"zip.vbs" echo(
>>"zip.vbs" echo(Set objShell = CreateObject("Shell.Application")
>>"zip.vbs" echo(
>>"zip.vbs" echo(Set source = objShell.NameSpace(InputFolder).Items
>>"zip.vbs" echo(
>>"zip.vbs" echo(objShell.NameSpace(ZipFile).CopyHere(source)
>>"zip.vbs" echo(
>>"zip.vbs" echo('Required!
>>"zip.vbs" echo(wScript.Sleep 2000
Der Ampersand hat eine besondere Bedeutung zu cmd
, ist es der Befehl Verkettungsoperator; Geben Sie beispielsweise echo abc & echo def
ein, um zwei echo
Befehle in einer einzigen Zeile zu setzen.
Um ein Literal &
auszugeben, müssen Sie es durch den Caret wie ^&
entkommen. Gleiches gilt für <
, >
und |
und die ^
selbst. Falls der echo
Befehl innerhalb eines geklammerten Codeblocks liegt, müssen Sie auch (
und )
fliehen, ansonsten ist es optional (daher empfehle ich, sie trotzdem zu entfernen).
Um eine leere Zeile auszugeben, verwenden Sie echo(
, da echo
den Ein/Aus-Status von Befehl-Echo zurückgibt, wie ECHO is on/off.
. Es gibt weit verbreitete Methoden wie echo.
und echo/
um das gleiche zu erreichen, aber es gibt Situationen, in denen sich diese merkwürdig verhalten. echo(
ist der einzige sichere Weg (obwohl seine Syntax ziemlich merkwürdig aussieht, muss ich zugeben). Übrigens, echo(
kann auch zum Echo nicht leeren Text verwendet werden.
Wenn Sie Befehl-Echoing global von einem nicht umgeleiteten @echo off
deaktivieren, müssen Sie nicht jeder weiteren Befehlszeile @
voranstellen.
Ich empfehle den Umleitungsteil (>>zip.vbs
) an den Anfang der Zeile in Ordnung zu bringen seltsame Verhalten zu vermeiden, falls die wiederholte Zeichenfolge mit einer einzelnen Ziffer endet, da dies als die Stromkennung für die Umleitung behandelt werden kann (0
ist STDIN, 1
ist STDOUT, 2
ist STDERR und 3
zu 9
sind undefiniert; <
ist die gleiche wie 0<
und >
/>>
ist die gleiche wie 1>
/1>>
). Beispiel: echo X=2>"zip.vbs"
würde X=
auf der Konsole als angezeigt. STDOUT wird nicht umgeleitet, und schreiben Sie nichts in als STDERR ist hier leer. Sie könnten dies vermeiden, indem Sie eine SPACE vor die >
einfügen, aber es würde auch Echo sein. Ein besserer Weg ist es, die gesamte echo
Befehlszeile zwischen ()
zu setzen, so dass die Zahl von >
getrennt wird. Aber die beste Lösung sollte das sein: >"zip.vbs" echo X=2
.
Sie können auch mehrere Umleitungen vermeiden und so viele Dateizugriffe, wenn Sie innerhalb eines parenthesised Block alle echos setzen sollten, die nur einmal umgeleitet wird (aber, wie oben beschrieben, nicht zu vergessen die Klammern, jetzt hier zu entkommen):
@echo off
> "zip.vbs" (
echo('Get command-line arguments.
echo(Set objArgs = WScript.Arguments
echo(InputFolder = objArgs^(0^)
echo(ZipFile = objArgs^(1^)
echo(
echo('Create empty ZIP file.
echo(CreateObject^("Scripting.FileSystemObject"^).CreateTextFile^(ZipFile, True^).Write "PK" ^& Chr^(5^) ^& Chr^(6^) ^& String^(18, vbNullChar^)
echo(
echo(Set objShell = CreateObject^("Shell.Application"^)
echo(
echo(Set source = objShell.NameSpace^(InputFolder^).Items
echo(
echo(objShell.NameSpace^(ZipFile^).CopyHere^(source^)
echo(
echo('Required!
echo(wScript.Sleep 2000
)
ist hier ein völlig anderer Ansatz, in dem nicht mehr entkommen getan werden muss. Das VBScript-Skript ist direkt nach dem ausführbaren Batch-Code in die Batch-Datei eingebettet. Damit dies funktioniert, müssen Sie exit /B
vor dem VBScript-Teil platzieren. Der VBScript-Teil wird dadurch identifiziert, dass er sich zwischen einem Paar von Zeilen befindet, die nur aus bestehen (dies bedeutet, dass die gesamte Batch-Datei einschließlich des VBScript-Teils keine solche Zeile enthalten darf; alternativ kann jeder VBScript-Zeile ein bestimmter Identifizierer vorangestellt werden) Präfix, das später entfernt wird, aber das Prinzip ist das gleiche). Mit dieser Methode werden die VBScript-Zeilen buchstäblich ausgegeben, es ist absolut kein Entkommen erforderlich. So hier gehen wir:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "FLAG="
> "zip.vbs" (
for /F "delims=" %%L in ('findstr /N /R "^" "%~f0"') do (
set "LINE=%%L"
setlocal EnableDelayedExpansion
set "LINE=!LINE:*:=!"
if not "!LINE:#=!"=="" (
if defined FLAG (echo(!LINE!)
) else (
endlocal
if defined FLAG (set "FLAG=") else (set "FLAG=#")
setlocal EnableDelayedExpansion
)
endlocal
)
)
endlocal
exit /B
################################################################################
'Get command-line arguments.
Set objArgs = WScript.Arguments
InputFolder = objArgs(0)
ZipFile = objArgs(1)
'Create empty ZIP file.
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
Set objShell = CreateObject("Shell.Application")
Set source = objShell.NameSpace(InputFolder).Items
objShell.NameSpace(ZipFile).CopyHere(source)
'Required!
wScript.Sleep 2000
################################################################################
Die gesamte Batch-Datei durch eine for /F
Schleife gelesen wird. Da dies leere Zeilen ignoriert, wird findstr
verwendet, um jeder Zeile mit ihrer Zeilennummer und einem Doppelpunkt zu vorangehen, der nicht leer zu for /F
erscheint. Dieses Präfix wird später in der Schleife entfernt. Die Variable FLAG
wird am Anfang gelöscht und wird umgeschaltet, sobald eine Zeile gefunden wurde, die nur aus Zeichen besteht. Wenn FLAG
nicht leer ist, wird die aktuelle Zeile ausgegeben, andernfalls nicht. Die verzögerte Erweiterung wird umgeschaltet, um keine Ausrufezeichen im Text zu verlieren.
Das Ampersand hat eine besondere Bedeutung für 'cmd', nämlich den Befehl Verkettungsoperator, wie' echo abc & echo def'; um ein literales '' '' 'zu hallen, müssen Sie es wie'^& '; Dasselbe gilt für '<', '>', '|' und '^', sowie '(' und ')', wenn der Befehl 'echo' in einem geklammerten Codeblock liegt. Um eine leere Zeile auszugeben, benutzen Sie 'echo ('. Ich empfehle, die Umleitung an den Anfang der Zeile zu setzen, wie '>>" zip.vbs "echo Some text.' oder' >> "zip.vbs" echo (' um nachfolgende Leerzeichen in der Ausgabe oder seltsames Verhalten zu vermeiden, falls das letzte Zeichen vor '>' eine Zahl ist – aschipfl
"^" vor jedem "&" zu addieren, hat perfekt funktioniert. Sieht so aus, als ob dein Kommentar eine Antwort sein sollte! Danke. –
Es kommt bald ... – aschipfl