用于 msbuild 的自定义 IL 重写插件

Custom IL Rewriting plugin for msbuild

我想创建一个将 IL rwriting 应用于我的输出程序集的自定义 msbuild 任务。

目前我已经在使用 PostSharp,现在尝试扩展重写功能。

对于某些特殊情况,我使用 Mono.Cecil 将一些代理类型重写到程序集中。这现在工作正常。

但现在我想拦截实际构建和 PostSharp 转换之间的构建过程,以便在我的代理类型上生成方面,这些方面将在下一步中由 PostSharp 实现。

我已经联系了 PostSharp 支持并得到了指导:

PostSharp injects itselft into a build process by overriding the MSBuild property CompileDependsOn (more info on MSDN https://msdn.microsoft.com/en-us/library/ms366724.aspx).

You can execute your own tasks after compilation but before PostSharp by overriding the CompileDependsOn property before the PostSharp.targets import statement in your *.csproj file.PostSharp injects itselft into a build process by overriding the MSBuild property CompileDependsOn (more info on MSDN https://msdn.microsoft.com/en-us/library/ms366724.aspx).

You can execute your own tasks after compilation but before PostSharp by overriding the CompileDependsOn property before the PostSharp.targets import statement in your *.csproj file.

我已经在 PostSharp.targets 文件中找到包含覆盖的位置:

<PropertyGroup Condition="'$(InjectPostSharp30)' != 'False'">
<PostSharp30DependsOn>
  $(PostSharp30DependsOn);
  PostSharp30ExtractBinaries;
  BeforePostSharpTransformation; // I added this one
  </PostSharp30DependsOn>
<PostSharpInspectDependsOn>
  $(PostSharpInspectDependsOn);
  PostSharp30InspectConstants;
  PostSharp30InspectReferences;
  PostSharp30DisablePreviousVersions
</PostSharpInspectDependsOn>
<CoreCompileDependsOn>
  PostSharpInspect;
  PostSharp30DefineConstant;
  $(CoreCompileDependsOn)
</CoreCompileDependsOn>
<CompileDependsOn>
  PostSharp30TimestampBeforeCompile;
  $(CompileDependsOn);
  PostSharp30TimestampAfterCompile;
  PostSharp30
</CompileDependsOn>
<BuildDependsOn>
  $(BuildDependsOn);
  PostSharp30Verify
</BuildDependsOn>
<CleanDependsOn>
  $(CleanDependsOn);
  PostSharp30Clean
</CleanDependsOn>

我也得到了我的 msbuild 任务 运行ning。它正在被调用,并且还为程序集提供了正确的路径,但是当构建实际被调用时,它被调用得太早并且找不到程序集,因为构建尚未完成。

如果我附加到 post 构建事件,PostSharp 已经 运行 但我需要它 运行 在我的自定义转换之后,以便使用方面实现我的类型。

我的测试任务是这样实现的:

    public class RewritingTask : Task
{
    [Required]
    public string OutputAssembly { get; set; }

    [Output]
    public string PreTransformationAssembly { get; set; }

    public override bool Execute()
    {
        string preTransformDir = Path.GetDirectoryName(OutputAssembly) + "\PreTransform\";

        if (!Directory.Exists(preTransformDir))
        {
            Directory.CreateDirectory(preTransformDir);
        }

        if (!File.Exists(OutputAssembly))
        {
            return false;
        }

        File.Copy(OutputAssembly, preTransformDir + Path.GetFileName(OutputAssembly), true);

        return true;
    }
}

错误是 FileNotFoundException,因为缺少输出程序集。

基本上我需要知道如何使用 msbuild 覆盖 CompileDependsOn 属性,就像描述的 postsharp 支持一样。我对 msbuild-scripts 不太熟悉,抱歉

转换目标的正确位置是

<CompileDependsOn>
    PostSharp30TimestampBeforeCompile;
    $(CompileDependsOn);
    HERE;
    PostSharp30TimestampAfterCompile;
    PostSharp30
</CompileDependsOn>

我的解决方案将 PostSharp 与我们的入口点完全分离:

<!-- If PostSharp is imported, override with combined targets -->
<PropertyGroup Condition="'$(InjectPostSharp30)' == 'True'">
    <CompileDependsOn>
        PostSharp30TimestampBeforeCompile;
        $(CompileDependsOn);
        ApplyILRewriting;
        PostSharp30TimestampAfterCompile;
        PostSharp30
    </CompileDependsOn>
    <BuildDependsOn>
        $(BuildDependsOn);
        PostSharp30Verify;
        AfterILRewritingPostBuild
    </BuildDependsOn>
</PropertyGroup>

<!-- If PostSharp is not imported, override with necessary targets -->
<PropertyGroup Condition="'$(InjectPostSharp30)' != 'True'">
    <CompileDependsOn>
        $(CompileDependsOn);
        HERE
    </CompileDependsOn>
    <BuildDependsOn>
        $(BuildDependsOn);
        AfterILRewritingPostBuild
    </BuildDependsOn>
</PropertyGroup>

所以我的脚本可以用于 PostSharp 和非 PostSharp 项目。