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.


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 :)


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)


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>

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.


6

Sie könnten Robocopy verwenden:

robocopy "$(TargetPath)" "$(SolutionDir)Prism4Demo.Shell\$(OutDir)Modules" /E

+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

1

Einfache kurze Antwort lautet:

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

0

Versuchen Sie / E.

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


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.