我的项目文件夹的 \lib 文件夹中有一些 dll 文件。在 dll 的属性页中,我选择了“构建操作”作为“内容”,将“复制到输出目录”选择为“始终复制”。
构建后,我实际上是在复制 dll,但它们在 \bin\Release\lib 中,而不是在 \bin\Release 中。
有没有办法将 dll 文件复制到 \bin\Release(而不是 \bin\Release\lib)而不编写构建后脚本或诉诸 nant 等?
我的项目文件夹的 \lib 文件夹中有一些 dll 文件。在 dll 的属性页中,我选择了“构建操作”作为“内容”,将“复制到输出目录”选择为“始终复制”。
构建后,我实际上是在复制 dll,但它们在 \bin\Release\lib 中,而不是在 \bin\Release 中。
有没有办法将 dll 文件复制到 \bin\Release(而不是 \bin\Release\lib)而不编写构建后脚本或诉诸 nant 等?
而不是<Content>
使用<ContentWithTargetPath>
并指定目标路径,如下所示:
<ItemGroup>
<ContentWithTargetPath Include="lib\some_file.dat">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>some_file.dat</TargetPath>
</ContentWithTargetPath>
<None Include="lib\some_file.dat" />
</ItemGroup>
请注意,此条目可能在 Visual Studio(2012、2015、2017)中不可见,但一旦手动添加到 csproj,它将出现在 Visual Studio 中。目标路径将无法通过 UI 进行编辑。
为该文件添加一个<None>
条目将确保它仍显示在 Visual Studio 的 UI 中。
保留它们$(ProjectDir)\Lib
,但将这些文件“作为链接”添加到 .csproj 的根目录。现在它们将被复制到 bin\Debug (或任何其他输出文件夹)而不在 lib 中。
编辑:当 ContentWithTargetPath 在我使用的 VS/MSBuild 版本中不可用时,这个答案被写回了。为可能不得不使用旧版本 VS 的人留下这个答案。请停止对此发表评论,我们都知道现在有更好的方法。
如果您的主要目的是在不弄乱项目根目录的情况下包含 DLL,另一种解决方案是将 DLL 移动到单独的共享项目中,并将其添加为原始项目中的引用。
(请注意,这篇文章没有直接回答这个问题,因为它不保留文件夹和项目结构,但我发现这种方法很有用,因为我能够在我的案例中重组我的项目,并且因为我想避免一些这里其他方法的缺点。)
脚步
Solution -> Add -> New Project -> Shared Project
Build Action: Content
和Copy to Output Directory: Copy Always
)References -> Add Reference -> Shared Projects
设置如下所示:
添加 dll 文件作为对项目的引用,并在引用上将“复制本地”设置为 true。
如果需要将Libs目录下的文件复制到VS2017的根文件夹:
<ItemGroup Condition="'$(Platform)' == 'x64'">
<None Include="Libs\x64\**" Link="\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup Condition="'$(Platform)' == 'x86'">
<None Include="Libs\x86\**" Link="\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
到任何其他文件夹,包括 Libs(RecursiveDir) 文件夹
<ItemGroup Condition="'$(Platform)' == 'x86'">
<None Include="Libs\x86\**" Link="mycustomfolder\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
要将我的帽子添加到此处,如果您想要包含整个目录的内容并且您不想在 Visual Studio 中跟踪每个单独的文件,那么您可以将其添加到您的项目文件中(对我来说,这是一个.vcxproj
文件UWP C++ 项目):
<ItemGroup>
<Content Include="Content\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
请注意,该Content
目录必须与项目文件位于同一目录中,以保留目录结构。
在 VisualStudio 2015 中,如果您“使用链接添加”的 dll位于同一项目的子文件夹中- 它们将自动放置在文件夹中,并且输出也放置在您看到的文件夹中。
如果 dll 在磁盘上的另一个项目或目录中,而不是在项目的子文件夹中,您可以“使用链接添加”,它们将被放在根目录中就好了。
上述解决方案对我来说在Visual Studio 2019 Professional v16.8.2
. 有时文件会复制,有时不会。经过多次尝试,感觉在 VS 的最新更新中可能出现了问题。
这个答案显示了如何使用构建后脚本...... OP 要求不要做的事情!因此,此答案仅适用于那些(像我一样)无法使用更传统方法的人。
lib
文件夹并选择要添加的项目Add
,单击向下箭头并选择Add As Link
Build Events
并添加以下 Post-build 事件,
rem Copy 3rd party DLL(s) to the output directory on successful build
COPY $(ProjectDir)lib\Something.dll $(TargetDir)
COPY $(ProjectDir)lib\SomethingElse.dll $(TargetDir)
请注意,您可以在构建后事件中使用通配符来复制多个文件。
另一种方法是将项目保留为 type None
。在解决方案资源管理器中,单击要部署的那些并将Content
属性设置为True
。
注意:我是在 VS2019 中做的,而且事情可能会因版本而异。
要让它工作,现在右键单击您的项目,然后选择“卸载项目”。然后右键单击卸载的项目并选择“编辑 project_name.vcxproj”。
在编辑器中,一直到文件底部并在尾随</Project>
标记之前插入此目标:
<Target Name="CopyContent" AfterTargets="Build">
<Copy SourceFiles="@(None)" Condition="'%(None.DeploymentContent)' == 'true'" DestinationFolder="$(OutputPath)" ContinueOnError="true" />
</Target>
现在右键单击卸载的项目并选择“重新加载项目”。如果出现提示,请选择保存并关闭。
我还设置OutputDirectory
为:
$(SolutionDir)bin\$(Configuration)\$(Platform)\
和IntermediateDirectory
到:
$(SolutionDir)obj\$(Configuration)\$(ProjectName)\$(Platform)\
在项目属性常规页面中。这会将输出放在“bin”文件夹中,并将中间体放在解决方案根目录中的“obj”文件夹中。
注意:$(SolutionDir)
从命令行运行 MSBuild 时未定义。您可以使用一个技巧来使用 GetDirectoryNameOfFileAbove 将其定义到 .sln 文件所在的文件夹。(留给读者作为练习)。此外,看起来他们在 2019 年无论如何都在命令行上正确处理了这个问题。是的:)$(SolutionDir)
包含一个尾随反斜杠,因此后面没有。每个结果都必须有一个尾随反斜杠。
现在,如果您拥有 Pro 或更高版本,请不要在每次需要创建项目时都这样做。那会很蹩脚。相反,一旦您按照自己喜欢的方式设置项目,请选择Project -> Export Template
. 你给它一个名字,下次你想创建一个像那个一样的项目时,只需在“新建项目”对话框中选择该名称。(在旧版本中,我认为这是Files -> Export Teamplate...
.)
关于您的问题,以下步骤在Visual Studio 2019中对我有用:
在 Visual Studio 编辑器中,对于您的 dll,将“构建操作”设置设置为“内容”(这可能是可选的),将“复制到输出目录”设置为“不复制”。
然后将在项目csproj文件中生成以下内容:
<ItemGroup>
<Content Include="lib\IncludedDLL.dll" />
</ItemGroup>
改为将条目修改为以下内容:
<ItemGroup>
<Content Include="lib\IncludedDLL.dll" />
<Content Include="lib\IncludedDLL.dll">
<Link>IncludedDLL.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
您可以将项目csproj文件中的"CopyToOutputDirectory"选项手动设置为"Always"或"PreserveNewest"。
在 Visual Studio 编辑器中,它仍然会显示文件“复制到输出目录”设置为“不复制”,但文件将在重建时复制到根输出目录。
如果您不想将文件复制到根输出目录,则不需要上述更改,因此,如果是这种情况,您可以手动删除项目 csproj 文件中的上述更改以恢复为非复制行为。
我在 Visual Studio 2010 / C# 项目中遇到了同样的问题。
对于程序集(即具有 .NET 接口),请使用解决方案资源管理器中项目下的文件夹“References”。右键单击它,选择“添加现有项目”并找到您的 .dll 程序集。
常见的 .dll 文件可以放在子文件夹中(如上面提到的“\lib”)并在属性中选择:
这完全符合我的要求 - 在构建期间,.DLL 被复制到没有“\lib”子文件夹的输出目录中。