有没有人碰巧知道一个技巧会阻止这个MSBuild任务阻塞?我真的只是想要打开资源管理器和构建脚本继续前进。目前,它会阻止Exec任务,直到资源管理器窗口关闭。
<Target Name="OpenExplorer">
<Exec Command='explorer.exe "$(DestinationDir)"' IgnoreExitCode="true" />
</Target>
谢谢!
编辑:我希望避免为此创建自定义任务。也许某些命令行魔法存在,可以内联到Command
?
答案 0 :(得分:10)
这是一种仅使用msbuild和内联任务异步执行进程的简单方法。这仅适用于 MSBuild V4.0 及以上(上帝保佑MSBuild家伙添加此功能!)。您不需要任何外部扩展包。
实际上,我们正在采用上面建议的代码并将其放入内联任务中。随意摆弄代码以满足您的需求。
此解决方案的重点在于,可让您实现结果,而无需为自定义任务创建单独的dll而头疼。扩展包中的实现肯定更加可靠,但这可以作为解决此问题的快速方法。您还可以准确地自定义运行方式。
<!--Launch a Process in Parallel-->
<UsingTask TaskName="ExecAsync" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<!--The file path is the full path to the executable file to run-->
<FilePath ParameterType="System.String" Required="true" />
<!--The arguments should contain all the command line arguments that need to be sent to the application-->
<Arguments ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<![CDATA[
string name = System.IO.Path.GetFileNameWithoutExtension(FilePath);
Log.LogMessage("Starting {0}...", name);
System.Diagnostics.ProcessStartInfo processStartInfo = new System.Diagnostics.ProcessStartInfo(FilePath, Arguments);
processStartInfo.UseShellExecute = true;
System.Diagnostics.Process.Start(processStartInfo);
Log.LogMessage("Finished running process {0}.", name);
]]>
</Code>
</Task>
</UsingTask>
然后,您可以按照以下方式从普通脚本中调用ExecAsync任务。注意:我的脚本用于收集应用程序的代码覆盖率。
<!--Start listening for coverage data:-->
<Message Text="Starting to listen for coverage..."/>
<ExecAsync FilePath='$(VSPerfCmdExePath)' Arguments='/start:coverage /output:"$(CoverageFilePath)"' ContinueOnError='true'/>
<Message Text="Listening for coverage..."/>
<!--Start App with Coverage:-->
<Message Text="Starting App..."/>
<Exec Command='"$(AppCoverageLatestExePath)"' ContinueOnError='true' WorkingDirectory='$(AppCoverageLatestFolder)'/>
<Message Text="App shut down."/>
<!--Stop gathering coverage results:-->
<Message Text="Stopping listening for coverage..."/>
<Exec Command='"$(VSPerfCmdExePath)" /shutdown'/>
<Message Text="Coverage shut down."/>
以下是对那里发生的事情的描述:
答案 1 :(得分:8)
您无法使用原生Exec
进行此操作。但是您可以编写自己的异步触发,如 this example :
public class AsyncExec : Exec {
protected override int ExecuteTool(string pathToTool,
string responseFileCommands,
string commandLineCommands) {
Process process = new Process();
process.StartInfo = GetProcessStartInfo(pathToTool, commandLineCommands);
process.Start();
return 0;
}
protected virtual ProcessStartInfo GetProcessStartInfo(string executable,
string arguments) {
if (arguments.Length > 0x7d00) {
this.Log.LogWarningWithCodeFromResources("ToolTask.CommandTooLong", new object[] { base.GetType().Name });
}
ProcessStartInfo startInfo = new ProcessStartInfo(executable, arguments);
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = true;
string workingDirectory = this.GetWorkingDirectory();
if (workingDirectory != null) {
startInfo.WorkingDirectory = workingDirectory;
}
StringDictionary environmentOverride = this.EnvironmentOverride;
if (environmentOverride != null) {
foreach (DictionaryEntry entry in environmentOverride) {
startInfo.EnvironmentVariables.Remove(entry.Key.ToString());
startInfo.EnvironmentVariables.Add(entry.Key.ToString(), entry.Value.ToString());
}
}
return startInfo;
}
}
然后您可以运行:
<AsyncExec Command="..." />
答案 2 :(得分:5)
在Starting a program with MSBuild/Web Deployment Project and not waiting for it
回答<Exec Command="..." Timeout="2000"></Exec>
答案 3 :(得分:4)
在MSBuild Extension Pack中尝试AsyncExec。
答案 4 :(得分:3)
Exec中的Command放在批处理文件中并执行。因此,您可以在命令中使用“start”关键字,就像在控制台窗口中一样。这样就可以了。