XCOPY-Schalter zum Erstellen eines angegebenen Verzeichnisses, falls es nicht vorhanden ist?

78

Ich verwende XCOPY in einem Post-Build-Ereignis, um kompilierte DLLs aus ihren Ausgabeordnern in den Ausgabeordner der Hauptanwendung zu kopieren. Die DLLs werden wie folgt in einen Unterordner "Module" im Hauptausgabeordner der App kopiert:

xcopy  "$(TargetPath)" "$(SolutionDir)Prism4Demo.Shell\$(OutDir)Modules\" 

Der Befehl funktioniert einwandfrei, wenn der Ordner "Module" vorhanden ist. Beim Testen habe ich jedoch festgestellt, dass XCOPY ihn nicht erstellt, wenn der Ordner nicht vorhanden ist, und der Befehl fehlschlägt.

Gibt es einen XCOPY-Schalter, mit dem der Ordner erstellt wird, wenn er nicht vorhanden ist? Wenn nicht, was würde ich meinem Post-Build-Ereignis hinzufügen, um den Ordner zu erstellen, wenn er nicht vorhanden ist? Danke für Ihre Hilfe.

David Veeneman
quelle
Siehe meinen Kommentar zur akzeptierten Antwort
David Veeneman

Antworten:

54

Ich habe dies in der Kommandozeile mit versucht

D:\>xcopy myfile.dat xcopytest\test\

und das Zielverzeichnis wurde ordnungsgemäß erstellt.

Wenn nicht, können Sie das Zielverzeichnis mit dem mkdirBefehl mit cmdaktivierten Befehlserweiterungen wie erstellen

cmd /x /c mkdir "$(SolutionDir)Prism4Demo.Shell\$(OutDir)Modules\"

('/ x' aktiviert Befehlserweiterungen, falls sie auf Ihrem System nicht standardmäßig aktiviert sind. Ich bin damit nicht so vertraut. cmd)

verwenden

cmd /? 
mkdir /?
xcopy /?

Für weitere Informationen :)

MartinStettner
quelle
13
Ich habe diese Antwort akzeptiert, weil sich der erste Teil als richtig herausgestellt hat. XCOPY wird das Verzeichnis erstellen, wenn es nicht bereits vorhanden ist . Ich habe festgestellt, dass Windows versucht hat, bei meinem XCOPY-Befehl eine Bestätigung zum Überschreiben anzufordern. VS erlaubt das nicht, also wurde es mit Code 2 beendet. Ich habe den Parameter / y hinzugefügt, der die Eingabeaufforderung unterdrückt, und der Befehl funktioniert. Getestet durch Bereinigen der Lösung und Löschen des Ordners und erneutes Erstellen. Ordner wurde von XCOPY erstellt.
David Veeneman
@DavidVeeneman Dies funktioniert nicht in VS2015 unter Windows 10; xcopy-Fehler mit der Meldung "Fehler: Ungültiger Pfad". Also nein. xcopy erstellt nicht (immer) das Zielverzeichnis
Tom Lint
3
XCOPY erstellt das Verzeichnis, dies jedoch nur, wenn keine Mehrdeutigkeit vorliegt: Dies ist nicht eindeutig: D: \> xcopy myfile.dat xcopytest \ test Dies ist nicht: D: \> xcopy myfile.dat xcopytest \ test \ ( Beachten Sie das letzte '\')
azog
120

Die Antwort auf "/ I" funktioniert, aber mit wenig Trick - im Ziel müssen Sie mit dem Zeichen \ enden, um xcopy mitzuteilen, dass das Ziel ein Verzeichnis und keine Datei ist!

Beispiel:

xcopy "$(TargetDir)$(TargetName).dll" "$(SolutionDir)_DropFolder" /F /R /Y /I

funktioniert nicht und gibt Code 2 zurück, aber dieser:

xcopy "$(TargetDir)$(TargetName).dll" "$(SolutionDir)_DropFolder\" /F /R /Y /I

In meinem Beispiel verwendete Befehlszeilenargumente:

/ F - Zeigt die vollständigen Namen der Quell- und Zieldateien an

/ R - Hiermit werden schreibgeschützte Dateien überschrieben

/ Y - Unterdrückt die Aufforderung, eine oder mehrere vorhandene Dateien zu überschreiben.

/ I - Nimmt an, dass das Ziel ein Verzeichnis ist (muss aber mit \ enden)

psulek
quelle
4
Die Antwort sollte nützlicher sein, wenn ausgearbeitet wurde, warum /F, warum /R, warum /Y. In meinem Fall wurde /Ydas Problem gelöst und zukünftige Leser würden davon profitieren zu wissen, warum ohne Data Mining das Internet.
Kaiser Orionii
Was ist, wenn ich zwei Verzeichnisse erstellen muss? Kann xcopy das für mich tun?
Pedro77
3
In meinem Fall /Iwar nicht erforderlich, um das Verzeichnis bedingt zu erstellen, sondern +1, um den Pfad mit Backslash zu beenden.
Kent Weigel
15

Ich hasse den PostBuild-Schritt, er erlaubt, dass zu viel außerhalb des Zuständigkeitsbereichs des Build-Tools passiert. Ich glaube, es ist besser, MSBuild den Kopiervorgang verwalten und die Aktualisierung durchführen zu lassen. Sie können die .csproj-Datei folgendermaßen bearbeiten:

  <Target Name="AfterBuild" Inputs="$(TargetPath)\**">
    <Copy SourceFiles="$(TargetPath)\**" DestinationFiles="$(SolutionDir)Prism4Demo.Shell\$(OutDir)Modules\**" OverwriteReadOnlyFiles="true"></Copy>
  </Target>
Ritch Melton
quelle
1
Ich denke, Ihre Eingaben, Quelldateien und Zieldateien sind nicht richtig. Er kopiert die DDL in den Modulordner, nicht umgekehrt.
Fun Mun Pieng
Ich würde sie sowieso zu einer Eigenschaftsgruppe hinzufügen.
Ritch Melton
1
Eingänge = "..." sollten entfernt werden. In VS 2012 wird die Fehlermeldung angezeigt, dass dem Ziel "AfterBuild" die Ausgabespezifikation fehlt. Wenn ein Ziel Eingaben deklariert, muss es auch Ausgaben deklarieren. "
Angularsen
$ (TargetPath) ist der Dateipfad zur Ausgabe-DLL-Datei und sollte daher wahrscheinlich auch \ ** aus dem SourceFiles-Wert entfernen.
Angularsen
Wenn Sie Inputs = "" entfernen, verlieren Sie das Build-Tracking. Dies ist eine zwei Jahre alte Frage. Wenn Sie sie aktualisieren möchten, können Sie sie gerne aktualisieren.
Ritch Melton
15

Verwenden Sie das / i mit xcopy. Wenn das Verzeichnis nicht vorhanden ist, wird das Verzeichnis für Sie erstellt.

GeekyGuy
quelle
6

Sie könnten Robocopy verwenden:

robocopy "$(TargetPath)" "$(SolutionDir)Prism4Demo.Shell\$(OutDir)Modules" /E
John Simons
quelle
+1: Ich wusste nichts über den Robocopy-Befehl in Vista und Win7. Vielen Dank. Glaube aber nicht, dass es hier funktionieren wird. Ich kopiere eher eine Datei als einen Ordner.
David Veeneman
Ich wusste auch nichts über Robokopie. Gut zu wissen, aber leider schlägt es mit der Meldung "Zugriff verweigert" fehl, wenn in einen Ordner unter "Programme" kopiert wird. (xcopy hat damit kein Problem.)
Tom Bogle
Nach weiteren Untersuchungen sieht es so aus, als würde xcopy gerne neue Dateien in vorhandene Ordner unter "Programme" kopieren, aber anscheinend kann es auch keine neuen Ordner erstellen (ohne Administratorzugriff).
Tom Bogle
1

Ich habe dies auf dem Befehl versucht. Es funktioniert für mich.

if "$(OutDir)"=="bin\Debug\"  goto Visual
:TFSBuild
goto exit
:Visual
xcopy /y "$(TargetPath)$(TargetName).dll" "$(ProjectDir)..\Demo"
xcopy /y "$(TargetDir)$(TargetName).pdb" "$(ProjectDir)..\Demo"
goto exit
:exit
Ankit Mori
quelle
1

Einfache kurze Antwort lautet:

xcopy /Y /I "$(SolutionDir)<my-src-path>" "$(SolutionDir)<my-dst-path>\"
zezba9000
quelle
0

Versuchen Sie / E.

So erhalten Sie eine vollständige Liste der Optionen: xcopy /?

Steve Wellens
quelle
Vielen Dank, aber / e dient zum Kopieren einer vorhandenen Unterverzeichnisstruktur in der Quelle. Ich kopiere eine Datei im Quellstamm in ein neues Unterverzeichnis im Ziel.
David Veeneman