繁体   English   中英

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

[英]MSBuild custom task depending on another project

我有一个奇怪的解决方案,我需要一个项目来“编译”另一个文件。

编译器(这里显示一个最小的例子)如下(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 + "\n\n" + DateTime.Now);

            generatedFileNames.Add(outputFileName);
        }

        this.OutputFiles = generatedFileNames.Select(name => new TaskItem(name)).ToArray();

        return true;
    }
}

如您所见,它只会改变输入文件的内容。

这是项目A - “编译器”库。

项目B,现在是主应用程序,有一个文件“lorem.txt”需要“编译”成“lorem.res.txt”并作为EmbeddedResource放在B.exe / B.dll中。

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

<PropertyGroup>
<CoreCompileDependsOn>$(CoreCompileDependsOn);InvokeMyCompile</CoreCompileDependsOn>
</PropertyGroup>
<UsingTask TaskName="MyCompiler.MyCompileTask" AssemblyFile="$(MSBuildProjectDirectory)\..\MyCompiler\bin\$(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中被盗的。)

最重要的部分是有效的,即当我更改lorem.txt和build时,lorem.res.txt会重新生成。

然而:

  • 当物理删除lorem.res.txt时,构建什么也不做(说它是最新的),直到我真正刷新VS中的项目。 因此,MSBuild并不“知道”构建项目实际上需要lorem.res.txt。
  • 更重要的是,当我更改项目A中的任何内容时,项目B会重新编译,但不会重新运行编译lorem.txt - > lorem.res.txt。 所以MSBuild并不“知道”转换依赖于另一个项目。

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

额外的问题:如何将输出文件(lorem.res.txt)标记为生成的EmbeddedResource,这样我就不必在VS中跟踪它,但它仍然被放入程序集中?

•当lorem.res.txt被物理删除时,构建不执行任何操作(说它是最新的),直到我实际刷新VS中的项目。 因此,MSBuild并不“知道”构建项目实际上需要lorem.res.txt。

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

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

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

额外的问题:如何将输出文件(lorem.res.txt)标记为生成的EmbeddedResource,这样我就不必在VS中跟踪它,但它仍然被放入程序集中?

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM