2010-03-05 2 views
12

이 MSBuild 태스크를 차단하지 못하게하는 트릭을 아는 사람이 있습니까? 나는 탐험가가 열리고 빌드 스크립트가 계속 실행 되기만을 바랄뿐입니다. 현재 탐색기 창이 닫힐 때까지 Exec 작업에서 차단됩니다.차단하지 않고 MSBuild exec 태스크

<Target Name="OpenExplorer"> 
    <Exec Command='explorer.exe "$(DestinationDir)"' IgnoreExitCode="true" /> 
</Target> 

고마워요!

편집 :이 작업에 대한 사용자 지정 작업을 만들지 않기를 바랬습니다. 아마도 Command의 인라인에 배치 할 수있는 명령 행 마법이 있습니까?

답변

7

네이티브 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="..." /> 
+0

이것이 유일한 옵션 인 경우 훌륭한 대답입니다. 그래도 그것을 피하기를 바랬습니다. – Rob

+0

참고이 코드는 MSBuild 4.0 인라인 작업 (http://msdn.microsoft.com/en-us/library/dd722601.aspx)을 사용하여 별도의 DLL을 컴파일 할 필요없이 인라인 할 수 있습니다 (편집 : 무시하십시오, 루크를 참조하십시오. –

5

명령에 Starting a program with MSBuild/Web Deployment Project and not waiting for it

<Exec Command="..." Timeout="2000"></Exec> 
+2

작업이 시간 초과 될 때 오류를 신호하지 않게하려면 ContinueOnError = "true"로 설정해야합니다. –

+0

@LewisJubb 더 설명해 주시겠습니까? 나를 위해, 그것은 경고를 어쨌든 제공하고, 그것은 효과가없는 것 같습니다. 어떤 버전의 MS 빌드를 사용하고 있습니까? –

+0

시간 초과가 발생하면 프로세스가 종료 된 것처럼 보입니다. 이것은 당신이 원하는 것이 아닐 수도 있습니다. – Nikolaj

3

에 답변 Exec은 배치 파일에 배치되어 실행됩니다. 따라서 콘솔 윈도우에서와 똑같은 명령에서 "start"키워드를 사용할 수 있습니다. 그것은 트릭을 할 것입니다.

+2

내 경험에 의하면 이것은 작동하지 않는 것 같습니다. 나는 그 일이 어떻게 든 그것을 막고 있다고 생각한다. –

7

다음은 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 작업을 호출 할 수 있습니다. 참고 : 아래 스크립트는 응용 프로그램의 코드 범위를 수집하는 데 사용됩니다. 이 범위를 수신하도록

  1. 먼저 내가 성능 도구를 킥오프 : 여기
    <!--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."/> 
    

    가 무슨 일이 일어나고 있는지에 대한 설명입니다. MSBuild (here 참조)에서 실행될 때 일반적으로 도구 블록이 차단되므로 AsyncExec 작업을 사용하여이 작업을 수행합니다.
  2. 다음으로 우리는 우리가 서비스를 받기를 원하는 프로그램을 시작합니다.
  3. 그런 다음 우리가 완료되면 커버리지 툴을 종료한다.
관련 문제