Msbuild directory.build.props:将存储在多级文件夹中的外部内容文件正确链接到.csproj
在度过了几天之后,我来到这里寻求帮助 情况是这样的——由于git存储库的大小增加,我们的构建占用了太多的时间。在进行构建之前,大部分时间都花在拉取一大组文件上。在进行构建之前,我们的Jenkins工作流将清除工作区,以确保不存在上一个构建的残余。事实证明,这些大型内容文件不会经常更改。因此,我将它们分离到一个不同的目录中,该目录与我现有的源代码文件具有类似的文件夹结构。这些内容文件保存在不同的存储库中,仅在需要时才提取。下面是我的文件夹结构:Msbuild directory.build.props:将存储在多级文件夹中的外部内容文件正确链接到.csproj,msbuild,projects-and-solutions,csproj,Msbuild,Projects And Solutions,Csproj,在度过了几天之后,我来到这里寻求帮助 情况是这样的——由于git存储库的大小增加,我们的构建占用了太多的时间。在进行构建之前,大部分时间都花在拉取一大组文件上。在进行构建之前,我们的Jenkins工作流将清除工作区,以确保不存在上一个构建的残余。事实证明,这些大型内容文件不会经常更改。因此,我将它们分离到一个不同的目录中,该目录与我现有的源代码文件具有类似的文件夹结构。这些内容文件保存在不同的存储库中,仅在需要时才提取。下面是我的文件夹结构: **ContentFiles**
**ContentFiles**
\ConsoleApp1\Content\TestData
New Bitmap Image.bmp
abc.xyz
cosoleDep1.txt
\Model\ConsoleApp2\Files
readme.txt
readme2.txt
\Model\Tools\ConsoleApp3\Packages
New Bitmap Image.bmp
New Text Document.txt
**Sources**
\ConsoleApp1
ConsoleApp1.csproj
\Model\ConsoleApp2
ConsoleApp2.csproj
\Model\Tools\ConsoleApp3
ConsoleApp3.csproj
ConsoleApp1.sln
Directory.Build.props
现在,我们来制作构建程序,将其中一些文件包含在源项目文件.csproj中,另一些文件包含在各自的输出文件夹中,以便进行打包和单元测试。我选择的选项是使用Directory.Build.props文件根据需要构建链接。因此,使用以下脚本在源代码的根级别添加了Directory.Build.props
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ContentFilesDir>$(MSBuildThisFileDirectory)\ContentFiles\</DependencyDir>
</PropertyGroup>
<ItemGroup>
<ContentFiles Include="$(ContentFilesDir)\**\$(MSBuildProjectName)\**\*.*"/>
</ItemGroup>
<ItemGroup>
<Content Include="@(ContentFiles)" >
<Link>%(RecursiveDir)\%(Filename)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>True</Visible>
</Content>
</ItemGroup>
</Project>
这里感兴趣的行是过滤器和
%RecursiveDir\%Filename%扩展名。我相信%RecursiveDir正在从列表中检索该项,并且名称从包含项目名称的最后一个反斜杠开始。因此,它正在处理的列表必须采用正确的格式。当项目处于多级文件夹结构中时,如何修改过滤器以删除该级别
必须有要求:内容文件必须在项目中显示为各个项目中的链接文件。如果我使用任何任务,那么它只会在构建任务期间生效,这可能会起作用,但不会显示在项目文件中
非常感谢您的帮助。在进一步了解了这项技术的工作原理后,我提出了以下建议。希望这对其他人有帮助。欢迎提出建议
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SourceDirName>Sources</SourceDirName>
<DependencyDirName>Dependencies</DependencyDirName>
<RootDir>$(MSBuildThisFileDirectory)</RootDir>
<DependencyDir>$([MSBuild]::NormalizePath($(MSBuildThisFileDirectory)..\Repo1\$(DependencyDirName)))</DependencyDir>
<SourceDir>$([MSBuild]::NormalizePath($(MSBuildThisFileDirectory)..\Repo2\$(SourceDirName)))</SourceDir>
<MSBuildProjectDirName>$([System.IO.Directory]::GetParent($(MSBuildProjectFullPath)).Name)</MSBuildProjectDirName>
</PropertyGroup>
<ItemGroup>
<DepFiles Include="$(DependencyDir)\**\$(MSBuildProjectDirName)\**\*.*"></DepFiles>
</ItemGroup>
<Target Name="Test" BeforeTargets="CopyFilesToOutputDirectory">
<Message Importance="Low" Text="MSBuildThisFileDirectory $(MSBuildThisFileDirectory)"/>
<Message Importance="Low" Text="SourceDirName $(SourceDirName)"/>
<Message Importance="Low" Text="DependencyDirName $(DependencyDirName)"/>
<Message Importance="Low" Text="RootDir $(RootDir)"/>
<Message Importance="Low" Text="DependencyDir $(DependencyDir)"/>
<Message Importance="Low" Text="SourceDir $(SourceDir)"/>
<Message Importance="Low" Text="MSBuildProjectDirName $(MSBuildProjectDirName)"/>
<Message Importance="Low" Text="@(DepFiles->Count())"/>
<Message Importance="Low" Text="@(DepFiles)->$([System.String]::Copy('%(FullPath)'))"/>
<Message Importance="Low" Text="@(DepFiles)->$([System.String]::Copy('%(FullPath)').Replace($(DependencyDir), $(SourceDir)))"/>
<Message Importance="Low" Text="@(DepFiles)->$([System.String]::Copy('%(FullPath)').Replace($(DependencyDir), $(SourceDir)).Replace($(MSBuildProjectDirectory),''))"/>
</Target>
<ItemGroup>
<Content Include="@(DepFiles)" Condition="'@(DepFiles->Count())' > 0">
<Link>$([System.String]::Copy('%(FullPath)').Replace($(DependencyDir), $(SourceDir)).Replace($(MSBuildProjectDirectory),''))</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>True</Visible>
</Content>
</ItemGroup>
</Project>
ConsoleApp1
\Content
New Bitmap Image.bmp
\TestData
abc.xyz
cosoleDep1.txt
Model\ConsoleApp2
\Files
readme.txt
readme2.txt
Model\Tools\ConsoleApp3
\Packages
New Bitmap Image.bmp
New Text Document.txt
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SourceDirName>Sources</SourceDirName>
<DependencyDirName>Dependencies</DependencyDirName>
<RootDir>$(MSBuildThisFileDirectory)</RootDir>
<DependencyDir>$([MSBuild]::NormalizePath($(MSBuildThisFileDirectory)..\Repo1\$(DependencyDirName)))</DependencyDir>
<SourceDir>$([MSBuild]::NormalizePath($(MSBuildThisFileDirectory)..\Repo2\$(SourceDirName)))</SourceDir>
<MSBuildProjectDirName>$([System.IO.Directory]::GetParent($(MSBuildProjectFullPath)).Name)</MSBuildProjectDirName>
</PropertyGroup>
<ItemGroup>
<DepFiles Include="$(DependencyDir)\**\$(MSBuildProjectDirName)\**\*.*"></DepFiles>
</ItemGroup>
<Target Name="Test" BeforeTargets="CopyFilesToOutputDirectory">
<Message Importance="Low" Text="MSBuildThisFileDirectory $(MSBuildThisFileDirectory)"/>
<Message Importance="Low" Text="SourceDirName $(SourceDirName)"/>
<Message Importance="Low" Text="DependencyDirName $(DependencyDirName)"/>
<Message Importance="Low" Text="RootDir $(RootDir)"/>
<Message Importance="Low" Text="DependencyDir $(DependencyDir)"/>
<Message Importance="Low" Text="SourceDir $(SourceDir)"/>
<Message Importance="Low" Text="MSBuildProjectDirName $(MSBuildProjectDirName)"/>
<Message Importance="Low" Text="@(DepFiles->Count())"/>
<Message Importance="Low" Text="@(DepFiles)->$([System.String]::Copy('%(FullPath)'))"/>
<Message Importance="Low" Text="@(DepFiles)->$([System.String]::Copy('%(FullPath)').Replace($(DependencyDir), $(SourceDir)))"/>
<Message Importance="Low" Text="@(DepFiles)->$([System.String]::Copy('%(FullPath)').Replace($(DependencyDir), $(SourceDir)).Replace($(MSBuildProjectDirectory),''))"/>
</Target>
<ItemGroup>
<Content Include="@(DepFiles)" Condition="'@(DepFiles->Count())' > 0">
<Link>$([System.String]::Copy('%(FullPath)').Replace($(DependencyDir), $(SourceDir)).Replace($(MSBuildProjectDirectory),''))</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<Visible>True</Visible>
</Content>
</ItemGroup>
</Project>