msbuild

时间:2016-06-01 13:31:39

标签: c# msbuild postsharp msbuild-task mono.cecil

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

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

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

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

我已经联系了PostSharp支持并获得了指示:

  

PostSharp通过覆盖MSBuild属性CompileDependsOn(在MSDN上发布更多信息https://msdn.microsoft.com/en-us/library/ms366724.aspx)将itselft注入构建过程。

     

您可以在编译之后但在PostSharp之前通过在* .csproj文件中的PostSharp.targets导入语句之前覆盖CompileDependsOn属性来执行您自己的任务.PostSharp通过覆盖MSBuild属性CompileDependsOn将itselft注入到构建过程中(更多信息,请参阅MSDN https://msdn.microsoft.com/en-us/library/ms366724.aspx)。

     

您可以在编译之后但在PostSharp之前通过在* .csproj文件中的PostSharp.targets导入语句之前覆盖CompileDependsOn属性来执行您自己的任务。

我已经在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任务也在运行。它被调用并且也为程序集提供了正确的路径,但是当构建实际被调用时,它被过早调用并且找不到程序集,因为构建尚未完成。

如果我附加到帖子构建事件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属性,就像所描述的postharp支持一样。我对msbuild-scripts不太熟悉,抱歉

1 个答案:

答案 0 :(得分:1)

转型目标的正确位置是

<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项目。