directory.build.props:将存储在多级文件夹中的外部内容文件正确链接到.csproj中

问题描述 投票:0回答:1

花了几天后,我在这里寻求帮助。

这里是情况-由于git存储库的大小增加,我们的构建花费了太多时间。花费的大部分时间是在进行构建之前提取大量文件。在进行构建之前,我们的Jenkins工作流程将清除工作空间,以确保不存在先前构建的残差。事实证明,这些大型内容文件不会经常更改。因此,我将它们分为与现有源代码文件类似的文件夹结构的不同目录。这些内容文件保存在其他存储库中,仅在需要时才拉出。这是我的文件夹结构:

    **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>

由于该文件,每个项目都将相应文件夹中的内容文件与其他位置的项目名称相链接。内容文件已正确复制到输出文件夹。尽管不应将某些文件复制到输出文件夹,但现在忽略这种情况。

现在是问题:文件夹结构不是我所期望的,我不知道该如何解决。如果看到的话,链接中还包括顶级文件夹名称。

ConsoleApp1
       \ConsoleApp1  <----
                   \Content
                    New Bitmap Image.bmp
                   \TestData
                         abc.xyz
                         cosoleDep1.txt
ConsoleApp2
       \Model\ConsoleApp2  <----  
                   \Files
                          readme.txt
                          readme2.txt
ConsoleApp3
       \Model\Tools\ConsoleApp3 <----
                   \Packages
                             New Bitmap Image.bmp
                             New Text Document.txt

我想得到的是以下内容(没有projectName作为内容文件的父项:]

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

这里感兴趣的行是过滤器<ContentFiles Include="$(ContentFilesDir)\**\$(MSBuildProjectName)\**\*.*"/><Link>%(RecursiveDir)\%(Filename)%(Extension)</Link>。我相信%(RecursiveDir)正在从列表中检索该项目,并且名称从包含项目名称的最后一个反斜杠开始。因此,它正在处理的列表必须采用正确的格式。当项目处于多级文件夹结构中时,如何修改过滤器,以便删除该级别?

必须具备的条件:内容文件必须在项目中显示为各个项目中的链接文件。如果我使用任何任务,那么它将仅在构建任务期间生效,并且可能会起作用,但不会显示在项目文件中

非常感谢您的帮助。

msbuild projects-and-solutions csproj
1个回答
0
投票

[了解了更多方法后,我提出了以下建议。希望这对其他人有帮助。欢迎提出建议!

<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>
© www.soinside.com 2019 - 2024. All rights reserved.