在应用程序构建期间自动复制文件以输出

Loo*_*oom 58 c++ msbuild visual-studio-2010 visual-c++

C#项目中的文件有" 复制到输出目录"属性.但是在VC++项目中却没有.我知道,我可以在VC++中使用Build事件并在那里写一些类似的东西

xcopy /y /d %(FullPath) $(OutDir)
Run Code Online (Sandbox Code Playgroud)

有没有办法避免使用CMD(和其他脚本方法)?在这种情况下,msbuild可以帮忙吗?

小智 92

在这种情况下,MSBuild可以做些什么来帮助吗?

使用MSVC 2012,这对我有用:

假设您的c ++项目中有一个文件"Data/ThisIsData.txt".

卸载项目(右键单击 - >卸载项目).
编辑项目XML(右键单击 - >编辑.vcxproj)
现在,您可以在编辑器中看到项目MSBuild文件为XML.

找到"ThisIsData.txt".它应该看起来像:

<ItemGroup>
<None Include="Data\ThisIsData.txt" />
...
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

现在添加其他项目组,如下所示:

<ItemGroup>
<Content Include="Data\ThisIsData.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
...
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

重新加载项目并构建.
您的文件"ThisIsData.txt"应该复制到$(OutDir)\ Data\ThisIsData.txt.

为什么重复ItemGroup?

好吧,如果您只是将None include更改为内容包含,IDE似乎不再喜欢它,并且不会显示它.因此,为了保持我的数据文件的快速编辑选项,我决定保留重复的条目.

  • 要将项目保留在IDE中,您还应该重命名.vcxproj.filters文件中的元素,将<None by <Content替换为您在.vcxproj中修改的相同文件 (4认同)
  • @Vertigo你所说的不是<true>,至少在visual studio 2017中.我得到的错误是"此项目项目提供者不支持项目类型内容" (2认同)

小智 17

在VS 2015中,可以为C项目提供C#中的功能.(建立jochen答案的想法.)而不是添加另一个ItemGroup,修改给定的itemgroup,添加一个CopyTo元素.IE,使用他的例子,只是增强原始条目:

<ItemGroup>
  <None Include="Data\ThisIsData.txt" />
    <DeploymentContent>true</DeploymentContent>
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
...
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

不需要其他ItemGroup.通过添加CopyTo元素,您可以添加"包含在项目中"属性.

包含在项目中的VS 2015 C物业已添加


Ant*_*n K 14

这取决于您使用的Visual Studio版本.Visual Studio 2008中VC++项目文件的格式不是MSBuild,因此在PostBuildStep中使用xcopy是一个不错的选择.

Visual Studio 2010中的VC++项目具有MSBuild格式.因此,存在MSBuild Copy任务的功能.

以下是一个示例:

<Copy
    SourceFiles="%(FullPath)"
    DestinationFolder="$(OutDir)"
/>
Run Code Online (Sandbox Code Playgroud)

如果目标目录不存在,则会自动创建

MSDN复制任务参考在此处

  • 我得到了一个C++解决方案,有5个vcproj文件,总共包含~4900行,所以我觉得这是一个有用的补充.它没有在提供的链接中直接解释,作为答案的链接通常是不受欢迎的.我自己寻找信息没有问题,但SO的目标之一是为了拯救我和其他那些工作,对吗? (7认同)
  • 很好的答案 - 这是我失踪的一步.我认为可以通过说明应该添加您提供的<Copy ... />代码的位置来改进它.(哪个文件,文件中的位置). (2认同)
  • 我需要另外将副本包装在<Target Name ="MyCopyTarget"AfterTargets ="Build"> </ Target>中我的目标元素是项目文件中根项目元素的元素. (2认同)

小智 14

在 Visual Studio 2017 中,您可以在 IDE 中执行此操作。我不确定早期版本。

只需将该文件添加为包含的项目文件,即可在解决方案资源管理器中显示。然后右键单击该文件并选择“属性”菜单。

将内容更改为“是”并将项目类型更改为“复制文件”

如果您查看它对项目文件所做的更改,您可以看到它添加了以下内容:

<ItemGroup>
  <CopyFileToFolders Include="Filename.txt">
    <DeploymentContent>true</DeploymentContent>
    <FileType>Document</FileType>
  </CopyFileToFolders>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

  • 这也是 Visual Studio 2019 的最佳解决方案。 (2认同)
  • 可以确认这在 VS 2017 中有效。谢谢@Eric。重申一下 - 确保右键单击并选择“属性”以打开“属性”对话框。当您仅选择文件时,“属性”视图(在“解决方案资源管理器”视图下)中不提供“项目类型”设置。当您刚刚选择文件时,您&lt;b&gt;可以&lt;/b&gt;将“内容”设置更改为“True”(相当于“属性”对话框中的“是”)。这可能看起来很迂腐,但它让我心痛了大约 30 分钟。 (2认同)

Waf*_*fle 6

henri-socha关于VS2015(可能是VS2013和VS2012,或任何使用MSBuild样式项目的东西)的回答之后,ItemGroup项类型很重要.

特别是<Text>项目似乎没有被复制,而<Content>项目则没有.

因此,对于包含文本文件ThisIsData.txt的项目目录Data,这将在目录下创建一个子目录Data,如果它更新,则将项目中的ThisIsData.txt文件复制到其中:$(OutDir)

<ItemGroup>
  <Content Include="Data\ThisIsData.txt">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </Content>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

这不会,但是如果将文本文件添加到项目中,Visual Studio IDE将插入该Content属性,并将属性设置为True.

<ItemGroup>
  <Text Include="Data\ThisIsData.txt">
    <DeploymentContent>true</DeploymentContent>
  </Text>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

换句话说,你需要通过IDE添加文件,使其意识到文件包含在项目中(添加<Text>标签ItemGroup),然后在文本编辑器中打开项目并添加<Content>标签ItemGroup以使其完成你想要什么.

我不确定<DeploymentContent>标签实际上做了什么.它可能是一个残余,因为我能找到的唯一的MSDN引用认为它已归档:https://msdn.microsoft.com/en-us/library/aa712517.aspx


小智 5

在 Visual Studio 2019 中,将文件设置为“包含在项目中”后,您可以编辑属性并选择项目类型“复制文件”(如 https://i.stack.imgur.com/vac2b.png所示),这可以避免手动 vcxproj 文件版本。