XCOPY切换到创建指定目录(如果不存在)?


78

我在构建后事件中使用XCOPY将编译的DLL从其输出文件夹复制到主应用程序的输出文件夹。DLL将被复制到主应用程序输出文件夹中的“ Modules”子文件夹中,如下所示:

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

如果Modules文件夹存在,则该命令运行正常,但是在测试过程中发现,如果该文件夹不存在,则XCOPY不会创建该文件夹,并且该命令失败。

是否存在一个XCOPY开关,如果该文件夹不存在,它将导致创建该文件夹?如果没有,如果该文件夹不存在,我将如何添加到构建后事件中以创建该文件夹?谢谢你的帮助。


请参阅我对已接受答案的评论
David Veeneman

Answers:


53

我在命令行上使用

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

并且目标目录已正确创建。

如果没有,您可以使用启用了的命令扩展名的mkdir命令来创建目标目录cmd

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

('/ x'启用命令扩展,以防您的系统默认情况下未启用它们,我不太熟悉cmd

使用

cmd /? 
mkdir /?
xcopy /?

了解更多信息 :)


13
我接受了这个答案,因为第一部分证明是正确的。XCOPY创建目录(如果尚不存在)。我发现Windows试图在我的XCOPY命令上要求覆盖确认。VS不允许这样做,因此它在代码2中退出。我添加了/ y参数,该参数禁止了该提示,并且该命令有效。通过清洁溶液并删除文件夹,然后重新构建进行了测试。文件夹是由XCOPY创建的。
David Veeneman

@DavidVeeneman在Windows 10下的VS2015中不起作用;xcopy错误,并显示消息“错误:无效路径”。所以不行。xcopy不会(总是)创建目标目录
Tom Lint

3
XCOPY会创建目录,但是只有在没有歧义的情况下,它才会这样做:这是模棱两可的:D:\> xcopy myfile.dat xcopytest \ test这不是:D:\> xcopy myfile.dat xcopytest \ test \(请注意最后一个'\')
azog

118

使用“ / I”的答案有效,但技巧不多-在目标中,您必须以字符\结尾,以告诉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-假设目标是目录(但必须以\结尾)


4
如果详细说明了为什么使用/F,为什么/R,为什么,答案应该更有用/Y。就我而言,/Y解决了这个问题,如果不进行Internet数据挖掘,那么将来的读者将从中受益。
Orionii皇帝13年

如果我需要创建两个目录怎么办?xcopy可以帮我吗?
Pedro77

3
就我而言,/I并不是有条件地创建目录所必需的,而是+1以反斜杠结束路径。
肯特·韦格尔

15

我讨厌PostBuild步骤,它允许在构建工具的权限范围之外发生太多事情。我相信最好让MSBuild管理复制过程并进行更新。您可以这样编辑.csproj文件:

  <Target Name="AfterBuild" Inputs="$(TargetPath)\**">
    <Copy SourceFiles="$(TargetPath)\**" DestinationFiles="$(SolutionDir)Prism4Demo.Shell\$(OutDir)Modules\**" OverwriteReadOnlyFiles="true"></Copy>
  </Target>

1
我认为您的输入,SourceFiles和DestinationFiles是不正确的。他正在将DDL复制到modules文件夹,而不是相反。
Fun Mun Pieng

无论如何,我都会将它们添加到属性组中。
里奇·梅尔顿

1
输入=“ ...”应被删除。在VS 2012中,我收到一条错误消息,即““ AfterBuild”目标缺少其输出规范。如果目标声明了输入,则它还必须声明输出。
angularsen 2013年

$(TargetPath)是输出.DLL文件的文件路径,因此也应该从SourceFiles值中删除\ **。
angularsen 2013年

如果删除Inputs =“”,则会失去构建跟踪。这是一个已有两年历史的问题,如果要更新,请随时进行。
里奇·梅尔顿

15

将/ i与xcopy一起使用,如果该目录不存在,它将为您创建目录。


6

您可以使用robocopy:

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

+1:我不知道Vista和Win7中可用的robocopy命令。谢谢。不过,不要认为它会在这里工作。我正在复制文件,而不是文件夹。
David Veeneman

我也不知道robocopy。众所周知,但不幸的是,如果复制到“程序文件”下的文件夹,它将失败并显示“拒绝访问”消息。(xcopy对此没有问题。)
Tom Bogle

经过进一步研究,看起来xcopy可能很乐意将新文件复制到Program Files下的现有文件夹中,但是显然也不能创建新文件夹(没有管理员访问权限)。
汤姆·博格尔

1

我在命令上尝试了这个。它正在为我工​​作。

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

简单的简短答案是这样的:

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

0

试试/ E

要获得选项的完整列表:xcopy /?


谢谢,但是/ e用于在源代码中复制现有的子目录结构。我正在将源根目录中的文件复制到目标中的新子目录。
David Veeneman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.