MSBuild自定义任务取决于另一个项目



我有一个奇怪的解决方案,我需要一个项目在另一个项目中"编译"文件。

编译器(这里显示一个最小的例子)如下(MSBuild自定义任务):

public class MyCompileTask : Task
{
    [Required]
    public ITaskItem[] InputFiles { get; set; }
    [Output]
    public ITaskItem[] OutputFiles { get; set; }
    public override bool Execute()
    {
        var generatedFileNames = new List<string>();
        foreach (var inputFile in this.InputFiles)
        {
            var inputFileName = inputFile.ItemSpec;
            var outputFileName = Path.ChangeExtension(inputFileName, ".res.txt");
            var source = File.ReadAllText(inputFileName);
            var compiled = source.ToUpper();
            File.WriteAllText(outputFileName, compiled + "nn" + DateTime.Now);
            generatedFileNames.Add(outputFileName);
        }
        this.OutputFiles = generatedFileNames.Select(name => new TaskItem(name)).ToArray();
        return true;
    }
}

如您所见,它只大写输入文件的内容。

这是A项目——"编译器"库。

项目B,目前主要的应用程序,有一个文件"loremm .txt"需要"编译"成"loremm .res.txt",并作为EmbeddedResource放在b.c exe/b.c dll中。

在b.s csproj中我添加了以下内容:

<PropertyGroup>
<CoreCompileDependsOn>$(CoreCompileDependsOn);InvokeMyCompile</CoreCompileDependsOn>
</PropertyGroup>
<UsingTask TaskName="MyCompiler.MyCompileTask" AssemblyFile="$(MSBuildProjectDirectory)..MyCompilerbin$(Configuration)MyCompiler.dll" />
<Target Name="MyCompile" Inputs="lorem.txt" Outputs="lorem.res.txt">
  <MyCompileTask InputFiles="lorem.txt">
    <Output TaskParameter="OutputFiles" PropertyName="OutputFiles" />
  </MyCompileTask>
</Target>
<Target Name="InvokeMyCompile" Inputs="lorem.txt" Outputs="lorem.res.txt">
  <Exec Command="&quot;$(MSBuildBinPath)MSBuild.exe&quot; /t:MyCompile &quot;$(ProjectDir)$(ProjectFileName)&quot;" />
</Target>
(2层目标和显式的msbuild.exe调用是另一个问题的解决方案。事实上,这个例子的大部分内容都是从Q.那里偷来的。

最重要的部分工作,即当我更改loremm .txt并构建loremm .res.txt时,loremm .res.txt会重新生成。

然而

:

  • 当loremm .res.txt被物理删除时,构建不做任何事情(说它是最新的),直到我在vs中实际刷新项目,所以MSBuild不"知道"loremm .res.txt实际上需要构建项目。
  • 更重要的是,当我改变项目A中的任何东西时,项目B会重新编译,但不会重新运行编译loremm .txt -> loremm .res.txt。所以MSBuild并不"知道"转换依赖于另一个项目。

如何在csproj文件中声明这些依赖关系?

附加问题:如何将输出文件(loremm .res.txt)标记为生成的EmbeddedResource,因此我不必在VS中跟踪它,但它仍然放入程序集?

•当loremm .res.txt被物理删除时,构建不做任何事情(说它是最新的),直到我在vs中实际刷新项目。因此,MSBuild不"知道"loremm .res.txt实际上需要构建项目。

我创建了一个演示并在我这边重现了您的问题,您可以使用msbuild命令行来避免它。

•更重要的是,当我更改项目A中的任何内容时,项目B会重新编译,但不会重新运行编译loremm .txt -> loremm .res.txt。因此MSBuild并不"知道"转换依赖于另一个项目。

由于自定义任务引用了DLL文件,当更改项目A中的任何内容时,您需要重新构建项目以生成更新的DLL文件。

附加问题:如何将输出文件(loremm .res.txt)标记为生成的EmbeddedResource,因此我不必在VS中跟踪它,但它仍然放入程序集?

您可以在BeforeBuild目标中添加自定义ItemGroup来实现它。

 <Target Name="BeforeBuild" DependsOnTargets="MyCompile">
    <ItemGroup>
      <Content Include="lorem.res.txt">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      </Content>
    </ItemGroup>
  </Target>

相关内容

  • 没有找到相关文章

最新更新