<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="MainFrameworkRegenerateFeatures" BeforeTargets="BeforeBuild">
<Message Importance="high" Text="Regenerating Feature Files" />
<Exec Command="$(ProjectDir)..packagesSpecFlow.3.0.1toolsSpecFlow.exe generateAll $(ProjectPath) /force /verbose"
Condition="Exists('$(ProjectDir)..packagesSpecFlow.3.0.1toolsSpecFlow.exe')" />
</Target>
<PropertyGroup>
<BuildDependsOn>
$(BuildDependsOn);
MainFrameworkRegenerateFeatures;
</BuildDependsOn>
</PropertyGroup>
</Project>
我有上面的目标文件,它被捆绑到 nuget 包的构建目录中。 安装软件包后,我可以看到它在 csproj 中进行了适当的条目。 注意 - 当我尝试调试它时,上面的目标文件已经采取了多种形式。 我最初没有属性组,但在听说这种方法可能是其他问题等的解决方法后,我把属性组放了进去。
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir).nugetNuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir).nugetNuGet.targets'))" />
<Error Condition="!Exists('..packagesMainFramework.0.15.0buildMainFramework.targets')" Text="$([System.String]::Format('$(ErrorText)', '..packagesMainFramework.0.15.0buildMainFramework.targets'))" />
</Target>
<PropertyGroup>
<PreBuildEvent>
</PreBuildEvent>
</PropertyGroup>
<Import Project="..packagesMainFramework.0.15.0buildMainFramework.targets" Condition="Exists('..packagesMainFramework.0.15.0buildMainFramework.targets')" />
因此,这是 nuget 的默认安装.exe当它将包安装到 csproj 中时。
当我通过Visual Studio运行构建时 - 目标正确触发。 我看到输出显示"重新生成功能文件",然后它告诉我重新生成了哪些功能文件。
但是,当我通过我开发的使用 MSBuild API 的自定义构建工具进行构建时,它会完全跳过 MainFrameworkRegenerateFeatures。
我的构建工具通过以下方式完成构建:
ProjectCollection pc = new ProjectCollection();
Dictionary<string, string> globalProperty = new Dictionary<string, string>();
globalProperty.Add("nodeReuse", "false");
BuildParameters bp = new BuildParameters(pc);
bp.Loggers = new List<Microsoft.Build.Framework.ILogger>()
{
new FileLogger() {Parameters = @"logfile=buildresult.txt", Verbosity = LoggerVerbosity.Diagnostic}
};
BuildRequestData buildRequest = new BuildRequestData(projectFilePath, globalProperty, "12.0",
new string[] { "Clean", "Build" }, null);
BuildResult buildResult = BuildManager.DefaultBuildManager.Build(bp, buildRequest);
BuildManager.DefaultBuildManager.Dispose();
pc = null;
bp = null;
buildRequest = null;
生成成功,但它从不执行目标文件 - 不会重新生成任何功能文件。
我有一个非常详细的日志文件,它告诉我以下内容:
在文件中定位"EnsureNuGetPackageBuildImports" "C:\ETRBuilder\BuildRunner\ETRun_9302082.1742918\CP.SolutionDir\CP.ProjectDir\IE.Project.csproj": 由于错误条件,任务"错误"被跳过;(!Exists('$(SolutionDir).nuget\NuGet.targets')) 被评估为 (!Exists('C:\ETRBuilder\BuildRunner\ETRun_9302082.1742918\CP.SolutionDir\.nuget\NuGet.targets')). 由于错误条件,任务"错误"被跳过;(!存在('..\packages\MainFramework.0.15.0\build\MainFramework.targets')) 被评估为 (!存在('..\packages\MainFramework.0.15.0\build\MainFramework.targets'))。 在项目"IE.项目.csproj"。
为什么这在Visual Studio中可以工作,但在MSBuild中却失败了?
关于如何解决这个问题的任何想法?
编辑 1: 手动针对解决方案文件运行 MSBuild.exe 时,它会执行目标并将功能文件重新生成为测试类。 似乎当它通过 API 完成并且仅当它位于这台特定机器上时,它才无法做到这一点。
GenerateTargetFrameworkMonikerAttribute: Skipping target "GenerateTargetFrameworkMonikerAttribute",因为所有输出文件都是 关于输入文件的最新信息。 MainFrameworkRegenerateFeatures: Regenerate Feature Files
C:\ETRBuilder\BuildRunner\ETRun_9372271.4822016\ClientName\ProjectFolder..\packages\SpecFlow.2.0.1\tools\SpecFlow.exe 全部生成 C:\ETRBuilder\BuildRunner\ETRun_9372271.4822016\ClientName\ProjectFolder\Client.csproj/force/verbose 处理项目:客户端项目等。
功能\旧版\冒烟测试\核心\核心.功能 ->测试已更新
我将尝试从 API 调用中删除 MSBuild 版本属性,以防它导致它。
我尝试将其作为解决方法 - 但是当它通过服务应用程序执行时,它仍然会跳过目标!! 但是,如果我通过命令行手动执行它 - 它工作正常并重新生成功能文件...... WTF是怎么回事??
public static bool BuildWithMSBuild(string solution)
{
string command = solution;
ProcessStartInfo psi = new ProcessStartInfo(PathToMSBuild());
psi.Arguments = command;
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
Process p = new Process();
p.StartInfo = psi;
p.Start();
var v = p.StandardOutput.ReadToEnd();
Console.Write(v);
p.WaitForExit(60000);
File.WriteAllText("buildresult.txt",v);
if (v.Contains("Build succeeded"))
{
return true;
}
return false;
}
现在,当通过Windows服务执行时,我无法使其工作。 它始终跳过自定义目标。
我必须通过 Process.Start on the specflow.exe 将再生步骤集成到我的构建任务中。
你是否也在编程上执行 nuget 还原?
由于看起来这正在评估为假:
Exists('$(SolutionDir).nugetNuGet.targets')