在运行时获取 $(SolutionDir)

发布于 2024-12-03 03:11:11 字数 3698 浏览 0 评论 0原文

我已经设法使用此任务在运行时获取 $(SolutionDir) 变量:

<Target Name="GenerateCode" Outputs="$(IntermediateOutputPath)ResourcesPath-Constants.cs">
  <Exec Command=
        "
        echo namespace SRE.Widgets.Blend &gt; $(IntermediateOutputPath)ResourcesPath-Constants.cs
        echo { &gt;&gt; $(IntermediateOutputPath)ResourcesPath-Constants.cs
        echo     public static partial class ResourcesPath &gt;&gt; $(IntermediateOutputPath)ResourcesPath-Constants.cs
        echo     { &gt;&gt; $(IntermediateOutputPath)ResourcesPath-Constants.cs
        echo         public static string SOLUTION_DIR = @&quot;$(SolutionDir)&quot;; &gt;&gt; $(IntermediateOutputPath)ResourcesPath-Constants.cs
        echo     } &gt;&gt; $(IntermediateOutputPath)ResourcesPath-Constants.cs
        echo } &gt;&gt; $(IntermediateOutputPath)ResourcesPath-Constants.cs
        " />
</Target>
<Target Name="CompileGeneratedCode">
  <ItemGroup>
    <Compile Include="$(IntermediateOutputPath)ResourcesPath-Constants.cs" />
  </ItemGroup>
</Target>
<PropertyGroup>
  <CompileDependsOn>
    GenerateCode;
    CompileGeneratedCode;
    $(CompileDependsOn);
  </CompileDependsOn>
</PropertyGroup>

我遇到的问题是,由于该任务没有“输入”,因此始终会构建该项目。这很奇怪,因为它破坏了增量编译。该项目用于不同的解决方案,我只希望在更改解决方案时对其进行编译。

我尝试使用 Inputs="$(SolutionPath)。如果您只使用一种解决方案,那么这种方法效果很好,但是当您使用另一种解决方案中的项目时,sln.cache 会损坏并永远停止构建任务。无论您是否删除“输入”变量。让它再次工作的唯一方法是删除 .sln.cache 文件。

方法可以停止项目的每次编译吗?

什么

有谁知道有 解决办法:

<Target Name="GenerateTmpCode">
  <Exec
    Command=
        "
        echo namespace SRE.Widgets.Blend &gt; $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        echo { &gt;&gt; $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        echo     public static partial class ResourcesPath &gt;&gt; $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        echo     { &gt;&gt; $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        echo         public static string SOLUTION_DIR = @&quot;$(SolutionDir)&quot;; &gt;&gt; $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        echo     } &gt;&gt; $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        echo } &gt;&gt; $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        fc $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp $(IntermediateOutputPath)ResourcesPath-Constants.g.cs
        "
    ContinueOnError="true">
    <Output PropertyName="CommandExitCode" TaskParameter="ExitCode"/>
  </Exec>
</Target>

<Target Name="GenerateCode"
        Condition="'$(CommandExitCode)'!='0'"
        Outputs="$(IntermediateOutputPath)ResourcesPath-Constants.cs"
        Inputs="$(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp" >
  <Exec Command=
        "
        copy $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp $(IntermediateOutputPath)ResourcesPath-Constants.g.cs
        " />
</Target>

<Target Name="CompileGeneratedCode">
  <ItemGroup>
    <Compile Include="$(IntermediateOutputPath)ResourcesPath-Constants.g.cs">
      <AutoGen>True</AutoGen>
    </Compile>
  </ItemGroup>
</Target>

<PropertyGroup>
  <CompileDependsOn>
    GenerateTmpCode;
    GenerateCode;
    CompileGeneratedCode;
    $(CompileDependsOn);
  </CompileDependsOn>
</PropertyGroup>

有两个第一个在临时文件中创建一个包含 $(solutiondir) 值的字符串的部分类,并将其与当前使用的部分类进行比较(如果需要),第二个将复制临时文件。

I've managed to get the $(SolutionDir) variable in runtime using this task:

<Target Name="GenerateCode" Outputs="$(IntermediateOutputPath)ResourcesPath-Constants.cs">
  <Exec Command=
        "
        echo namespace SRE.Widgets.Blend > $(IntermediateOutputPath)ResourcesPath-Constants.cs
        echo { >> $(IntermediateOutputPath)ResourcesPath-Constants.cs
        echo     public static partial class ResourcesPath >> $(IntermediateOutputPath)ResourcesPath-Constants.cs
        echo     { >> $(IntermediateOutputPath)ResourcesPath-Constants.cs
        echo         public static string SOLUTION_DIR = @"$(SolutionDir)"; >> $(IntermediateOutputPath)ResourcesPath-Constants.cs
        echo     } >> $(IntermediateOutputPath)ResourcesPath-Constants.cs
        echo } >> $(IntermediateOutputPath)ResourcesPath-Constants.cs
        " />
</Target>
<Target Name="CompileGeneratedCode">
  <ItemGroup>
    <Compile Include="$(IntermediateOutputPath)ResourcesPath-Constants.cs" />
  </ItemGroup>
</Target>
<PropertyGroup>
  <CompileDependsOn>
    GenerateCode;
    CompileGeneratedCode;
    $(CompileDependsOn);
  </CompileDependsOn>
</PropertyGroup>

The problem i have is that, as the task has no "Inputs", this project is always built. This is weird because it breaks the incremental compilation. This project is used in diferent solutions and I only want it to be compiled if I change of solution.

I've tried to use Inputs="$(SolutionPath). This works well if you only use one solution but when you use the project from another solution the sln.cache gets corrupted and stops building the task forever. No matter if you remove the "Inputs" variable. The only way to get it working again is to delete the .sln.cache file.

Does anyone know any way to stop the every-time-compilation of the project?

EDIT:

Ok. I've found the solution:

<Target Name="GenerateTmpCode">
  <Exec
    Command=
        "
        echo namespace SRE.Widgets.Blend > $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        echo { >> $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        echo     public static partial class ResourcesPath >> $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        echo     { >> $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        echo         public static string SOLUTION_DIR = @"$(SolutionDir)"; >> $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        echo     } >> $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        echo } >> $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp
        fc $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp $(IntermediateOutputPath)ResourcesPath-Constants.g.cs
        "
    ContinueOnError="true">
    <Output PropertyName="CommandExitCode" TaskParameter="ExitCode"/>
  </Exec>
</Target>

<Target Name="GenerateCode"
        Condition="'$(CommandExitCode)'!='0'"
        Outputs="$(IntermediateOutputPath)ResourcesPath-Constants.cs"
        Inputs="$(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp" >
  <Exec Command=
        "
        copy $(IntermediateOutputPath)ResourcesPath-Constants.g.cs.tmp $(IntermediateOutputPath)ResourcesPath-Constants.g.cs
        " />
</Target>

<Target Name="CompileGeneratedCode">
  <ItemGroup>
    <Compile Include="$(IntermediateOutputPath)ResourcesPath-Constants.g.cs">
      <AutoGen>True</AutoGen>
    </Compile>
  </ItemGroup>
</Target>

<PropertyGroup>
  <CompileDependsOn>
    GenerateTmpCode;
    GenerateCode;
    CompileGeneratedCode;
    $(CompileDependsOn);
  </CompileDependsOn>
</PropertyGroup>

There are two targets. The first one creates a partial class containing a string with the $(solutiondir) value in a temporary file and compares it with the current partial class used. The second one copy the temporary file over the current if it is necessary.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文