Переключатель XCOPY для создания указанного каталога, если он не существует?

Я использую XCOPY в событии после сборки, чтобы скопировать скомпилированные библиотеки DLL из их выходных папок в выходную папку основного приложения. Библиотеки DLL копируются в подпапку «Модули» в основной выходной папке приложения, например:

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

Команда работает нормально, если папка Modules существует, но во время тестирования я обнаружил, что если папка не существует, XCOPY не создает ее, и команда не работает.

Есть ли переключатель XCOPY, который приведет к созданию папки, если она не существует? Если нет, что бы я добавил к своему событию после сборки, чтобы создать папку, если она не существует? Спасибо за вашу помощь.


person David Veeneman    schedule 03.03.2011    source источник
comment
См. Мой комментарий к принятому ответу   -  person David Veeneman    schedule 16.03.2011


Ответы (8)


Я пробовал это в командной строке, используя

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

и целевой каталог был правильно создан.

Если нет, вы можете создать целевой каталог с помощью команды mkdir с включенными расширениями команд cmd, например

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

('/ x' включает расширения команд, если они не включены по умолчанию в вашей системе, я не так хорошо знаком с cmd)

использовать

cmd /? 
mkdir /?
xcopy /?

для дополнительной информации :)

person MartinStettner    schedule 03.03.2011
comment
Я принял этот ответ, потому что первая часть оказалась верной. XCOPY создаст каталог, если он еще не существует. Я обнаружил, что Windows пытается запросить подтверждение перезаписи моей команды XCOPY. VS не позволяет этого, поэтому он вышел с кодом 2. Я добавил параметр / y, который подавляет запрос, и команда работает. Проверено очисткой раствора и удалением папки с последующим восстановлением. Папка создана XCOPY. - person David Veeneman; 03.03.2011
comment
@DavidVeeneman Это не работает в VS2015 под Windows 10; xcopy с сообщением error: Invalid path. Так что нет. xcopy не будет (всегда) создавать целевой каталог - person Tom Lint; 10.10.2016
comment
XCOPY создает каталог, но это будет сделано только в том случае, если нет двусмысленности: Это неоднозначно: D: \ ›xcopy myfile.dat xcopytest \ test Это не: D: \› xcopy myfile.dat xcopytest \ test \ ( обратите внимание на последний '\') - person azog; 01.12.2017

Ответ на использование "/ I" работает, но с небольшой хитростью - в target вы должны заканчивать символ \, чтобы указать xcopy, что цель - это каталог, а не файл!

Пример:

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

не работает и возвращает код 2, но этот:

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

Аргументы командной строки, использованные в моем примере:

/ F - отображает полные имена исходного и целевого файлов.

/ R - это перезапишет файлы, доступные только для чтения

/ Y - подавляет запрос на перезапись существующего файла (ов)

/ I - Предполагается, что местом назначения является каталог (но должен оканчиваться на \)

person psulek    schedule 27.03.2012
comment
Ответ был бы более полезным, если бы он был подробно разъяснен: зачем использовать /F, почему /R, почему /Y. В моем случае /Y решил проблему, и будущим читателям было бы полезно знать, почему без интеллектуального анализа данных в Интернете. - person Emperor Orionii; 18.06.2013
comment
Что, если мне нужно создать два каталога? Может ли xcopy сделать это для меня? - person Pedro77; 04.10.2013
comment
В моем случае /I не требовался для условного создания каталога, а +1 для завершения пути обратной косой чертой. - person Kent Weigel; 30.11.2016
comment
TIL, что исследование параметров командной строки - это интеллектуальный анализ данных в Интернете. :) - person Tony; 11.05.2021

Я ненавижу этап PostBuild, он позволяет слишком многим вещам происходить за пределами компетенции инструмента сборки. Я считаю, что лучше позволить MSBuild управлять процессом копирования и выполнять обновление. Вы можете отредактировать файл .csproj следующим образом:

  <Target Name="AfterBuild" Inputs="$(TargetPath)\**">
    <Copy SourceFiles="$(TargetPath)\**" DestinationFiles="$(SolutionDir)Prism4Demo.Shell\$(OutDir)Modules\**" OverwriteReadOnlyFiles="true"></Copy>
  </Target>
person Ritch Melton    schedule 03.03.2011
comment
Я думаю, что ваши Inputs, SourceFiles и DestinationFiles неправильные. Он копирует DDL в папку модулей, а не наоборот. - person Fun Mun Pieng; 03.03.2011
comment
Я бы все равно добавил их в группу свойств. - person Ritch Melton; 03.03.2011
comment
Inputs = ... следует удалить. В VS 2012 я получаю сообщение об ошибке, заключающееся в том, что цель AfterBuild не имеет выходной спецификации. Если цель объявляет входы, она также должна объявлять выходы. - person angularsen; 20.11.2013
comment
$ (TargetPath) - это путь к выходному файлу .DLL, поэтому, вероятно, также следует удалить \ ** из значения SourceFiles. - person angularsen; 20.11.2013
comment
Если вы удалите Inputs =, вы потеряете отслеживание сборки. Это вопрос двухлетней давности, если вы хотите его обновить, не стесняйтесь. - person Ritch Melton; 20.11.2013

Используйте / i с xcopy, и если каталог не существует, он создаст каталог для вас.

person GeekyGuy    schedule 07.05.2011

Вы можете использовать robocopy:

robocopy "$(TargetPath)" "$(SolutionDir)Prism4Demo.Shell\$(OutDir)Modules" /E
person John Simons    schedule 03.03.2011
comment
+1: Я не знал о команде robocopy, доступной в Vista и Win7. Спасибо. Но не думаю, что здесь это сработает. Копирую файл, а не папку. - person David Veeneman; 03.03.2011
comment
Я тоже не знал о робокопии. Полезно знать, но, к сожалению, это не удается с сообщением «Доступ запрещен» при копировании в папку в разделе «Программные файлы». (У xcopy с этим проблем нет.) - person Tom Bogle; 07.10.2016
comment
После дальнейшего изучения, похоже, что xcopy может копировать новые файлы в существующие папки в Program Files, но, по-видимому, также не может создавать новые папки (без доступа администратора). - person Tom Bogle; 07.10.2016
comment
Вот как использовать Robocopy в пакетном файле для копирования только файла (требуется SET file =% 1 и SET filepath =% ~ dp1 и SET filename = % ~ n1 и SET destination = c: \ path \ folder): ROBOCOPY% filepath%% destination% % filename% / B / COPY: DT / XJ / SL / R: 0 / W: 0 / V (пробел в% filepath% важен, а не ошибка). - person Ed999; 03.05.2021

Я пробовал это по команде. У меня работает.

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
person Ankit Mori    schedule 30.03.2018

Простой короткий ответ таков:

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

Попробуйте / E

Чтобы получить полный список опций: xcopy /?

person Steve Wellens    schedule 03.03.2011
comment
Спасибо, но / e предназначен для копирования существующей структуры подкаталогов в исходном коде. Я копирую файл из исходного корня в новый подкаталог в месте назначения. - person David Veeneman; 03.03.2011