MSBuild:在另一个 CodeTaskFactory 目标中重用方法
MSBuild: re-use method from one CodeTaskFactory target in another one
由于描述不完善已更新。
我已经为“BeforeBuild”目标创建了这个 CodeTaskFactory MSBuild 任务:
<UsingTask
TaskName="WriteIntoFileIfDifferent"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
<ParameterGroup>
<FileName ParameterType="System.String" Required="True" Output="False"/>
<Text ParameterType="System.String" Required="True" Output="False"/>
</ParameterGroup>
<Task>
<Code Type="Class" Language="cs">
<![CDATA[
...
public class WriteIntoFileIfDifferent : Task
{
...
public override bool Execute ()
{
...
CopyFileIfNeeded (tempFileName, m_fileName);
...
}
private void CopyFileIfNeeded (string i_sourceFileName,
string i_targetFileName)
{
...
CheckFileCopyNeeded (i_sourceFileName, i_targetFileName))
...
}
private static bool CheckFileCopyNeeded (string i_sourceFileName,
string i_targetFileName)
{
...
return !CheckStreamContentsEqual (sourceFileStream, targetFileStream);
...
}
private static bool CheckStreamContentsEqual (FileStream i_sourceFileStream,
FileStream i_targetFileStream)
{
...
}
}
]]>
</Code>
</Task>
</UsingTask>
现在我已经创建了另一个相同类型的任务,也是为“BeforeBuild”目标创建的,它现在正在调用这两个任务。这两个任务都包含一个“CopyFileIfNeeded()”方法;它实际上是一个普通副本。
如何从两个任务中提取方法 CopyFileIfNeeded()
并将其放在一个单独的地方,以便两个任务都可以使用它?
这可能吗?
如果是,我如何在我的任务中调用这个方法?
如果有人对完整代码感兴趣,我可以在这里添加。
不确定如何使用 CodeTaskFactory 跨任务重新执行代码;这可能取决于如何准确地实施这些。例如。如果他们根据提供的代码创建一个 dll,您可以找出可以引用哪个 dll 并使用它的功能。但是,与其弄清楚是否是这种情况,我们也可以自己编写确切的原理:
使用通用代码创建一个文件,Common.cs
:
namespace Foo
{
public static class Bar
{
public static bool CopyFileIfDifferent(string A, string B)
{
return true;
}
}
}
如果需要,即时构建该文件(应该仅在源文件更改或 dll 由于使用输入和输出而不存在时构建):
<PropertyGroup>
<CommonDll>$(Temp)\Common.dll</CommonDll>
</PropertyGroup>
<Target Name="BuildCommonDll" Inputs="$(MSBuildThisFileDirectory)Common.cs" Outputs="$(CommonDll)">
<Csc Sources="$(MSBuildThisFileDirectory)Common.cs"
References="System.dll;mscorlib.dll"
TargetType="Library" OutputAssembly="$(CommonDll)"/>
</Target>
在您的任务中引用内置的 dll:
<UsingTask
TaskName="WriteIntoFileIfDifferent"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
<ParameterGroup>
<FileName ParameterType="System.String" Required="True" Output="False"/>
<Text ParameterType="System.String" Required="True" Output="False"/>
</ParameterGroup>
<Task>
<Reference Include="$(CommonDll)" />
<Code Type="Class" Language="cs">
<![CDATA[
using Foo;
public class WriteIntoFileIfDifferent : Microsoft.Build.Utilities.Task
{
public string FileName{ get; set;}
public string Text{ get; set;}
public override bool Execute ()
{
var result = Foo.Bar.CopyFileIfDifferent(FileName, Text);
Log.LogMessage("result = " + result.ToString());
return true;
}
}
]]>
</Code>
</Task>
</UsingTask>
在调用它的目标中确保 dll 构建是一个依赖项:
<Target Name="Build" DependsOnTargets="BuildCommonDll">
<WriteIntoFileIfDifferent FileName="A" Text="B"/>
</Target>
第一个 运行 的输出:
Project "c:\temp\foo.targets" on node 1 (Build target(s)).
BuildCommonDll:
C:\Program Files (x86)\Microsoft Visual Studio17\Community\MSBuild.0\bin\Roslyn\csc.exe /reference:System
.dll /reference:mscorlib.dll /out:c:\temp\Common.dll /target:library c:\temp\Common.cs
Build:
result = True
Done Building Project "c:\temp\foo.targets" (Build target(s)).
连续运行s的输出:
Project "c:\temp\foo.targets" on node 1 (Build target(s)).
BuildCommonDll:
Skipping target "BuildCommonDll" because all output files are up-to-date with respect to the input files.
Build:
result = True
Done Building Project "c:\temp\foo.targets" (Build target(s)).
由于描述不完善已更新。
我已经为“BeforeBuild”目标创建了这个 CodeTaskFactory MSBuild 任务:
<UsingTask
TaskName="WriteIntoFileIfDifferent"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" >
<ParameterGroup>
<FileName ParameterType="System.String" Required="True" Output="False"/>
<Text ParameterType="System.String" Required="True" Output="False"/>
</ParameterGroup>
<Task>
<Code Type="Class" Language="cs">
<![CDATA[
...
public class WriteIntoFileIfDifferent : Task
{
...
public override bool Execute ()
{
...
CopyFileIfNeeded (tempFileName, m_fileName);
...
}
private void CopyFileIfNeeded (string i_sourceFileName,
string i_targetFileName)
{
...
CheckFileCopyNeeded (i_sourceFileName, i_targetFileName))
...
}
private static bool CheckFileCopyNeeded (string i_sourceFileName,
string i_targetFileName)
{
...
return !CheckStreamContentsEqual (sourceFileStream, targetFileStream);
...
}
private static bool CheckStreamContentsEqual (FileStream i_sourceFileStream,
FileStream i_targetFileStream)
{
...
}
}
]]>
</Code>
</Task>
</UsingTask>
现在我已经创建了另一个相同类型的任务,也是为“BeforeBuild”目标创建的,它现在正在调用这两个任务。这两个任务都包含一个“CopyFileIfNeeded()”方法;它实际上是一个普通副本。
如何从两个任务中提取方法 CopyFileIfNeeded()
并将其放在一个单独的地方,以便两个任务都可以使用它?
这可能吗?
如果是,我如何在我的任务中调用这个方法?
如果有人对完整代码感兴趣,我可以在这里添加。
不确定如何使用 CodeTaskFactory 跨任务重新执行代码;这可能取决于如何准确地实施这些。例如。如果他们根据提供的代码创建一个 dll,您可以找出可以引用哪个 dll 并使用它的功能。但是,与其弄清楚是否是这种情况,我们也可以自己编写确切的原理:
使用通用代码创建一个文件,
Common.cs
:namespace Foo { public static class Bar { public static bool CopyFileIfDifferent(string A, string B) { return true; } } }
如果需要,即时构建该文件(应该仅在源文件更改或 dll 由于使用输入和输出而不存在时构建):
<PropertyGroup> <CommonDll>$(Temp)\Common.dll</CommonDll> </PropertyGroup> <Target Name="BuildCommonDll" Inputs="$(MSBuildThisFileDirectory)Common.cs" Outputs="$(CommonDll)"> <Csc Sources="$(MSBuildThisFileDirectory)Common.cs" References="System.dll;mscorlib.dll" TargetType="Library" OutputAssembly="$(CommonDll)"/> </Target>
在您的任务中引用内置的 dll:
<UsingTask TaskName="WriteIntoFileIfDifferent" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll" > <ParameterGroup> <FileName ParameterType="System.String" Required="True" Output="False"/> <Text ParameterType="System.String" Required="True" Output="False"/> </ParameterGroup> <Task> <Reference Include="$(CommonDll)" /> <Code Type="Class" Language="cs"> <![CDATA[ using Foo; public class WriteIntoFileIfDifferent : Microsoft.Build.Utilities.Task { public string FileName{ get; set;} public string Text{ get; set;} public override bool Execute () { var result = Foo.Bar.CopyFileIfDifferent(FileName, Text); Log.LogMessage("result = " + result.ToString()); return true; } } ]]> </Code> </Task> </UsingTask>
在调用它的目标中确保 dll 构建是一个依赖项:
<Target Name="Build" DependsOnTargets="BuildCommonDll"> <WriteIntoFileIfDifferent FileName="A" Text="B"/> </Target>
第一个 运行 的输出:
Project "c:\temp\foo.targets" on node 1 (Build target(s)).
BuildCommonDll:
C:\Program Files (x86)\Microsoft Visual Studio17\Community\MSBuild.0\bin\Roslyn\csc.exe /reference:System
.dll /reference:mscorlib.dll /out:c:\temp\Common.dll /target:library c:\temp\Common.cs
Build:
result = True
Done Building Project "c:\temp\foo.targets" (Build target(s)).
连续运行s的输出:
Project "c:\temp\foo.targets" on node 1 (Build target(s)).
BuildCommonDll:
Skipping target "BuildCommonDll" because all output files are up-to-date with respect to the input files.
Build:
result = True
Done Building Project "c:\temp\foo.targets" (Build target(s)).