MSBuild 项可以使用目标设置的属性吗?

Rab*_*820 5 c# msbuild csproj msbuild-task visual-studio

我试图使用 MSBuild 实现以下目标:我的主项目 ( MyProject.csproj) 应包含几个Reference项目,但其中一个项目的路径是由目标设置的属性Reference值。SomeProperty具体来说, 的值SomeProperty是使用ReadLinesFromFileTask.

以下是 的高级结构MyProject.csproj

<Project>
  <Target Name="CreateSomeProperty">
    <!-- Tasks that ultimately set $(SomeProperty) by parsing a value with ReadLinesFromFileTask -->
  </Target>
  <ItemGroup>
    <Reference Include="$(SomeProperty)" />
    <!-- Other Reference items -->
  </ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)

不幸的是,这个设置不起作用。Dependencies我在 VS 解决方案资源管理器中的节点下看到那些黄色小三角形MyProject,因为该项目正在寻找缺少字符的路径中的 DLL。The type or namespace name could not be found同样,当我构建项目时,即使我仍然看到Message目标内任务的输出,我也会收到一堆错误。据推测,在评估阶段加载项目失败CreatePathProperty后,目标正在执行阶段运行。Reference

有没有办法让这样的设置有效?我尝试过在元素BeforeTargets="Build"中设置Target,然后InitialTargets="CreateSomeProperty"Project元素中设置,但似乎没有任何效果。任何帮助将非常感激!

Lan*_*SFT 3

MSBuild 项可以使用目标设置的属性吗?

是的,我确信如果你在.net framework project with old csproj format并且你想要的是 VS2017 中支持的场景,这是可能的(仅在 VS2017 中进行了测试)。

尖端:

通常在执行您的自定义目标之前msbuild读取Propertiesand 。Items因此,我们应该使用类似的方法BeforeTargets="BeforeResolveReferences"来确保这种情况下的正确顺序是custom target runs=>create the property=>msbuild reads the info about references and the property.

否则顺序(错误顺序何时BeforeTargets="Build"或什么)应该是:Msbuild reads the info about references(now the property is not defined yet)=>the target runs and creates the property

解决方案: 将此脚本添加到 xx.csproj 的底部。

  <!-- Make sure it executes before msbuild reads the ItemGroup above and loads the references -->
  <Target Name="MyTest" BeforeTargets="BeforeResolveReferences">
    <ItemGroup>
      <!-- Define a TestFile to represent the file I read -->
      <TestFile Include="D:\test.txt" />
    </ItemGroup>
    <!-- Pass the file to read to the ReadLinesFromFile task -->
    <ReadLinesFromFile File="@(TestFile)">
      <!--Create the Property that represents the normal hintpath(SomePath\DLLName.dll)-->
      <Output TaskParameter="Lines" PropertyName="HintPathFromFile" />
    </ReadLinesFromFile>
    <!-- Output the HintPath in output log to check if the path is right -->
    <Message Text="$(HintPathFromFile)" Importance="high" />
    <ItemGroup>
      <Reference Include="TestReference">
        <!--It actually equals:<HintPath>D:\AssemblyFolder\TestReference.dll</HintPath>-->
        <HintPath>$(HintPathFromFile)</HintPath>
      </Reference>
    </ItemGroup>
  </Target>
Run Code Online (Sandbox Code Playgroud)

此外:

test.txt我用其内容为的文件进行了测试:

在此输入图像描述

我不确定文件的实际内容(和格式),但如果您只有D:\AssemblyFolder\该文件中的路径,则应该将其传递D:\AssemblyFolder\+YourAssemblyName.dll<HintPath>元数据。因为默认 reference格式hintpath如下所示:

  <Reference Include="ClassLibrary1">
      <HintPath>path\ClassLibrary1.dll</HintPath>
  </Reference>
Run Code Online (Sandbox Code Playgroud)

注意路径格式!希望我的回答有帮助:)