我花了几天的时间,终于找到了一个似乎有效的解决方案。然而,它似乎有点脆弱,或者可能是不明智的。
我希望所有非系统引用的程序集(当前使用的项目库是 NuGet 管理的)都包含在构建输出的“libs”子文件夹中。
我的 csproj 文件底部包含的以下代码段执行此操作(通过谷歌搜索和我在这里找到的几个问题构建。)
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. -->
<Target Name="BeforeBuild">
<Message Text="### Removing existing 'lib' folder" Importance="high" />
<RemoveDir Directories="$(TargetDir)libs" />
</Target>
<Target Name="MoveLibrariesOnBuild" AfterTargets="Build">
<ItemGroup>
<Libraries Include="%(Reference.HintPath)" >
<MissingHintPath>$([MSBuild]::ValueOrDefault('%(Reference.HintPath)', '').Equals(''))</MissingHintPath>
</Libraries>
</ItemGroup>
<Message Text="### Moving libraries to 'libs' ###" Importance="high" />
<Copy SourceFiles="@(Libraries)"
DestinationFiles="$(TargetDir)libs\%(Filename).dll"
Condition="%(Libraries.MissingHintPath) == False"
SkipUnchangedFiles="false"
OverwriteReadOnlyFiles="true" />
</Target>
</Project>
我尝试使用 Reference.Identity 和 Reference.Filename,但 Filename 还包含版本、文化等信息(因此不会正确重命名,除非我尝试使用内联字符串替换。)
你的意见?有没有更简单的方法,我是不是想多了?
我基于引用构建了一个列表,并使用 HintPath(仅存在于非标准程序集)作为我应该包含的标志。然后,在我的 MoveLibrariesOnBuild 目标中, MissingHintPath 用作条件标志。
根据我发现的建议,我避免使用 CopyLocal(它为引用生成一个 True 属性)。例如,What is the best practice for "Copy Local" and with project references?
我看到其他人提出了类似的问题,但似乎没有人回答或完整。也许,在社区的一些批评下,这可以成为有用的资源。
PS:我也尝试过使用 xcopy 和 robocopy 来使用项目构建事件,但事实证明这些事件更不可靠(并且难以调试。)
此外,这依赖于设置探测路径,如此处所述,C#: Custom assembly directory
PPS:如果您在删除/覆盖文件时遇到“文件正在使用”问题,您可能需要取消选中“启用 Visual Studio 托管进程”,如 here 所述
最佳答案
这是一个老问题,但在此过程中,MSBuild 为项目引用引入了一个看似未记录的“DestinationSubDirectory”元数据选项。我之所以知道这一点,是因为我花了很多时间来分解 Microsoft.Common.targets 本身,看看它是如何工作的。
像这样使用:
<ItemGroup>
<ProjectReference Include="..\Utilities\Company.Project.Utilities.csproj">
<Project>{ea7de0b6-aaba-42e7-97ae-bb33877db2a4}</Project>
<Name>Company.Project.Utilities</Name>
<DestinationSubDirectory>libs\</DestinationSubDirectory>
</ProjectReference>
</ItemGroup>
您的 dll 将被复制到位于项目输出目录中的“libs”子文件夹中。
关于c# - 引用到单独的子文件夹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24336265/