使用Visual Studio复制文件?

13

我希望创建一个 Visual Studio 项目(我使用的是 VSTS 2008),它可以简单地进行文件复制工作。更具体地说,我会向这个项目添加一些文件,当我构建该项目时,这个项目将把包含在项目中的文件复制到某个目标位置。

有什么思路可以在 VSTS 中实现这个功能吗?

顺便说一句:我听说使用 proj 文件可以完成这样的任务,但我没有找到任何适合初学者学习的好样例。:-)

谢谢提前, George


你为什么不能创建一个批处理或命令文件来进行复制? - JB King
@JB King,我想将所有内容集成/包装到msbuild中。有什么想法或推荐的示例吗? - George2
6个回答

13

你可以在Visual Studio中添加一个构建后步骤:

  • 打开项目属性(对于C#项目有效,我猜VB.NET也适用)。
  • 选择“生成事件”选项卡。
  • 在那里可以添加构建后事件命令,例如

    copy $(ProjectDir)\bin\* SOME_OTHER_FOLDER\*

$(ProjectDir)是一个宏,还有一些其他的可用,在编辑命令时会显示出来。

然后,如果你查看相应的项目文件(XYZ.csproj或XYZ.vbproj),你会看到文件底部添加了一个属性组,例如:

  <PropertyGroup>
      <PostBuildEvent>copy $(ProjectDir)\bin\* SOME_OTHER_FOLDER\*</PostBuildEvent>
  </PropertyGroup>

如果直接编辑MSBuild文件,就可以实现这一点。请注意,您无需启动Visual Studio即可构建并将文件复制,只需将项目文件传递给msbuild.exe即可。


1
我会使用xcopy,因为它更加安全可靠。 - KJAWolf
1
PostBuildEvent 不是一个“很好”的解决方案,因为它不检查依赖项。也就是说,如果被复制的文件之一发生更改,后期生成将无法检测到并且不会重新运行。 - okigan
2
如果需要复制文件,即使它们将被覆盖,请使用“Copy /Y source destination”命令来复制文件。 - northben
Okigan,你能提供一个“伟大”的解决方案吗?也许你不知道,但我很想知道你是否有更多的信息 =) - Martin Andersson
1
我在谷歌上搜索并发现“robocopy c:\source c:\target /mir”非常有用。它不仅可以复制,而且实际上可以镜像源目录。因此,/mir标志可能会删除在目标中未找到的文件。请参见此链接 - Martin Andersson

5

如前所述,Visual Studio .xxproj 文件实际上是 MSBuild 文件。因此,您可以在其中执行 MSBuild 允许的任何操作。我已经使用它们来自定义我的构建过程。在您的情况下,您要寻找的是 Copy Task。您可以将其添加到 AfterBuild 目标中。


这也是我的第一反应,但他问的是在VS(TS)中如何实现。 - kay.herzam
1
是的,那又怎样?这不是他想要的吗?当项目构建完成时,其中的文件会被复制到某个位置。他甚至可以玩弄很多变量。 - Vilx-

0
在Visual Studio 2010中,您可以使用自定义构建工具
例如,此规则将“faq.txt”复制到输出目录。
<ItemGroup>
  <CustomBuild Include="faq.txt">
    <Message>Copying readme...</Message>
    <Command>copy %(Identity) $(OutDir)%(Identity)</Command>
    <Outputs>$(OutDir)%(Identity)</Outputs>
  </CustomBuild>
</ItemGroup>

0

对于一个不那么强大但更本地化的解决方案:

在Visual Studio中,打开项目“配置属性” ->“高级”,并将“复制内容到输出目录”设置为“是”。假设您要复制的文件是解决方案的一部分,请打开要复制的文件的属性,并将“内容”设置为“是”。请记得在发布和调试配置中都这样做。

现在,您的文件将在编译时复制到输出目录中。适用于复制配置或图形等资产文件。

(我使用的是Visual Studio 2022,早期版本可能无法使用)


0

C#/VB.NET 项目文件是 MSBuild 脚本。MSBuild 可以满足你的所有需求...


没错,但问题是如何实现问题中的要求? - AnthonyWJones
我了解MSBuild。我想找一些现成的/参考样例来进行文件复制。有什么推荐吗? - George2
请查看此文件(MSI,但仅安装示例),其中包含MSBuild示例和相关的文档:http://download.microsoft.com/download/d/4/0/d401e5cd-04c7-4b72-b644-a00ae3fd5681/msbuildqs.msi - Lucero
已安装并找到了一些好的示例,但没有找到一个可直接使用的文件复制示例。你能推荐一个示例让我快速开始解决我的困惑吗? :-) - George2
1
这是一个简单的示例: http://www.sedodream.com/PermaLink,guid,8f6bbb30-ec22-4fc6-90a1-c32715598d23.aspx - Lucero

0
这个问题的其他答案往往假设您没有使用VisualStudio而是直接使用MSBuild,或者拥有一个现有项目,可以添加自定义构建步骤或构建事件(我发现构建事件类型的解决方案容易出错,因为它们并不总是在需要复制文件时进行复制)。
如果您想要一个仅执行复制操作的VisualStudio项目,您可以使用带有“Makefile”项目的标准VisualStudio 来完成此操作。
稍微有些误导性的Makefile项目可以做任何你可以从命令行中做的事情。显然,这意味着你可以创建一个只复制文件的Makefile项目。在Makefile项目的属性配置属性NMake部分中,有构建、重建和清除操作的字段。这些字段可以填充普通的批处理文件命令。在每次构建时,VisualStudio将从适当的字段创建一个临时批处理文件,并使用cmd执行它。警告在64位机器上,你将得到32位的cmd解释器,因此如果你想访问64位的Windows命令或DLL,你需要使用神奇的sysnative目录(我不确定这是否有文档记录,所以它可能并不总是这样——你的批处理脚本应该能够抵御cmd位数的变化)。
需要64位系统文件的示例批处理代码,而不知道先前运行代码的cmd或操作系统(32位或64位):
if /i "%programfiles%"=="%programfiles(x86)%" if /i not "%programfiles%"=="%programw6432%" (
    REM 32 bit cmd on 64-bit computer
    REM Use the 'sysnative' fake directory to get to 64-bit system32 files
) else (
    if /i not "%programfiles%"=="%programfiles(x86)%" if /i "%programfiles%"=="%programw6432%" (
        REM 64 bit cmd on 64-bit computer
        REM Use the 'system32' directory to get to 64-bit system32 files
    ) else (
        echo "Cannot do 64-bit on 32-bit computer"
        copy foobar
    )
)

(上面的“copy foobar”行将失败,导致构建失败。)

请注意,VisualStudio(和MSBuild)将始终运行Makefile项目 - 它不会检查输出文件的时间戳,而是将该工作推迟到它期望的其他构建工具(nmake、cmake、make、ant、maven等)。由于在这种情况下只有一个简单的复制命令,而没有一些程序检查是否执行复制,因此每次构建都会发生复制。

VisualStudio始终运行makefile项目也意味着每次按F5调试项目时,VisualStudio都会用措辞不当的弹出对话框(如果您没有告诉它不要这样做)来烦扰您,告诉您您的项目已过期,必须再次构建它。如果您告诉VisualStudio不显示对话框,它将在运行可执行文件之前执行复制而不询问。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接