gpt4 book ai didi

.net - 如何在 Rider 中触发文件更改的设计时构建?

转载 作者:行者123 更新时间:2023-12-02 00:55:13 27 4
gpt4 key购买 nike

我做了一个 NuGet package它在设计和构建时从 DSL 文件生成 C# 代码。它在 Visual Studio 中运行良好,但在 Rider 中存在一些问题(我将在下面描述)。

在 Visual Studio 中

包声明 custom items用于 DSL 文件,并为它们分配一个 MSBuild:Compile Generator元数据,触发 design-time build每次文件更改时在 Visual Studio 中。

然后,自定义目标 Hook 到构建 BeforeTargets="CoreCompile" .它生成 C# 代码并添加 Compile项目的项目。目标在正常和设计时构建中运行,并支持 incremental builds以避免不必要的工作。

这是相关的(简化和注释的)MSBuild 代码:
props文件:

<Project>

<!-- Define the item type with its default metadata -->
<ItemDefinitionGroup>
<ZebusMessages>
<Generator>MSBuild:Compile</Generator>
</ZebusMessages>
</ItemDefinitionGroup>

<!-- Make the item type user-visible in VS -->
<ItemGroup>
<AvailableItemName Include="ZebusMessages" />
<PropertyPageSchema Include="$(MSBuildThisFileDirectory)ZebusMessages.xml" />
</ItemGroup>

<!-- Include all .msg files by default -->
<ItemGroup>
<ZebusMessages Include="**\*.msg" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>

</Project>
targets文件:

<Project>

<ItemGroup>
<!-- Add a GeneratorTargetPath metadata for the target file -->
<ZebusMessages Update="@(ZebusMessages)" GeneratorTargetPath="$([MSBuild]::ValueOrDefault('$(IntermediateOutputPath)ZebusMessages/%(RecursiveDir)%(FileName)%(Extension).cs', '').Replace('\', '/'))" />

<!-- Remove all None items for .msg files -->
<None Remove="**\*.msg" />
</ItemGroup>

<Target Name="GenerateZebusMessages"
BeforeTargets="CoreCompile"
Condition="'@(ZebusMessages)' != ''"
Inputs="@(ZebusMessages)"
Outputs="@(ZebusMessages->'%(GeneratorTargetPath)')">

<!-- Generate output files -->
<GenerateZebusMessagesTask InputFiles="@(ZebusMessages)" />

<ItemGroup>
<!-- Add the output items -->
<Compile Include="@(ZebusMessages->'%(GeneratorTargetPath)')" Visible="false" />
<FileWrites Include="@(ZebusMessages->'%(GeneratorTargetPath)')" />
</ItemGroup>
</Target>

</Project>

完整文件是 available here .

在 Rider

用 Rider 2018.3.3 测试:

这在 Rider 中不是开箱即用的,因为它似乎不像 VS 那样触发设计时构建。

起初,Rider 完全不知道生成的 C# 文件,这导致它在引用生成的类的代码中显示错误。

我用的是 Rider 的 internal mode它公开了对项目的“重新加载项目和显示日志”操作,这表明 Rider 在项目加载时调用具有以下目标的 MSBuild:

GenerateAssemblyInfo;_CheckForInvalidConfigurationAndPlatform;GetFrameworkPaths;ResolvePackageDependenciesDesignTime;CollectPackageReferences;BeforeResolveReferences;ResolveAssemblyReferences;ResolveComReferences;ResolveSDKReferences;ResolveCodeAnalysisRuleSet



注意缺少 CompileDesignTimeCompile在那个列表中。

所以我添加了以下目标来支持 Rider:

  <Target Name="GenerateZebusMessagesRiderDesignTime"
Condition="'$(BuildingByReSharper)' == 'true'"
AfterTargets="PrepareForBuild"
DependsOnTargets="GenerateZebusMessages" />

它 Hook 到 PrepareForBuild其中 ResolveAssemblyReferences取决于,并调用 GenerateZebusMessages .

这让 Rider 知道生成的文件,但我想解决一些问题:
  • 如果我编辑 .msg 文件,则生成的 C# 代码仅在项目构建时更新,而 Rider 的代码完成在此之前不是最新的。
  • 如果我将 .msg 文件添加到项目中,我需要重新加载项目以将其考虑在内。构建项目在这里没有帮助。



  • 我想让 Rider 调用 MSBuild 目标并在编辑或添加/删除 .msg 文件时重新评估项目。

    我只在添加文件时在日志中发现以下内容,但没有太大帮助:
    10:54:05.076 |I| ProjectModel                   | RequestBuilder thread:7        | Add item ZebusMessages = 'OtherFile.msg'...
    10:54:05.076 |I| ProjectModel | RequestBuilder thread:7 | Item matches to a wildcard pattern, mark project as dirty
    10:54:05.095 |I| ProjectModel | RequestBuilder thread:7 | Project file content requested: ZebusMessages.csproj
    10:54:08.330 |I| ProjectModel | RequestBuilder thread:7 | Item with EvaluatedInclude 'OtherFile.msg' was already changed. Perform project reevaluation before processing.
    10:54:08.361 |I| ProjectModel | RequestBuilder thread:7 | Project 'ZebusMessages.csproj' was reevaluated in 22 ms, EvaluationCounter: 9

    在此时间范围内,日志中没有其他内容提及 MSBuild。

    当给定的文件类型更改时,是否可以触发类似于 Rider 中的设计时构建的内容?

    或者更一般地说,在什么情况下 Rider 会调用 MSBuild 来重新评估项目?

    最佳答案

    我有两个故事给你——一个短的和一个长的 =)

    简短的故事

    它应该在即将发布的 2019.1 EAP 1 中开箱即用

    漫长的故事

    Rider(与 Visual Studio 不同)在项目加载阶段不执行设计时构建。我们认为它太贵了(特别是对于基于 .net sdk 的项目)。因此 Rider 会评估每个项目,然后构建一些预定义目标集以获取生成的文件和程序集引用。

    有时它会导致问题(比如这个),所以在 2019.1 中,我们实现了额外的算法来扫描所有导入的目标并寻找自定义 item-factory目标。据我所知,您的目标非常适合,因此 Rider 将能够找到它并与预定义的目标一起构建。

    如果它以某种方式不起作用,您仍然有两个选择:

  • 我们已经改写 Build Tools选项页面,因此您可以将任何自定义目标添加到加载过程
  • 在这里提出问题:https://youtrack.jetbrains.com/newIssue?project=Rider我会尽快解决你的问题。这些问题对我们来说是最优先的。
  • 关于.net - 如何在 Rider 中触发文件更改的设计时构建?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54745217/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com