0

I need to run a process during an MSBuild task, and close that process gracefully after doing some other operations. I cannot use kill as it just brutally terminates the process and it leaves some things in a bad state.

The process in question is RavenDB, and it supports quitting by entering a q in standard input. This is what the MSBuild tasks looks like (shortened):

"RavenDBQuit"

<UsingTask TaskName="RavenDBQuit"
           ...
    <ParameterGroup>
        <ProcessId Required="true" ParameterType="System.Int32" />
    </ParameterGroup>

    <Task>
        <Using Namespace="System.Diagnostics" />
        <Code Type="Fragment" Language="cs">
        <![CDATA[
        var process = Process.GetProcessById(this.ProcessId);
        process.StandardInput.WriteLine("q");
        ]]>
        </Code>  
    </Task>
</UsingTask>

"RavenDBStart

<UsingTask TaskName="RavenDBStart"
    <ParameterGroup>   
        ...
        <ProcessId ParameterType="System.Int32" Output="true" />
    </ParameterGroup>

    <Task>
        <Using Namespace="System.Diagnostics" />
        <Code Type="Fragment" Language="cs">
        <![CDATA[
        var process = new Process
        {
            StartInfo =
            {
                FileName = this.FileName,
                WorkingDirectory = this.WorkingDirectory,
                Arguments = this.Arguments,
                UseShellExecute = false,                    
                CreateNoWindow = true,
                RedirectStandardInput = true
            }
        };

        process.Start();

        this.ProcessId = process.Id;
        ]]>
        </Code>  
    </Task>
</UsingTask>

I get an error:

system.InvalidOperationException: StandardIn has not been redirected.

It would appear that you cannot write to a Process' standard input after retrieving it by ID, you will need to use the same object.

Can I do something else? I tried passing the process object directly between tasks but that is not supported.

My last resort is to use kill anyway after some wait time, hoping that RavenDB has done everything it needed to do by then.

MarioDS
  • 12,895
  • 15
  • 65
  • 121
  • Why cant your task RavenDBStart wait for a signal from outside to go ahead and type q in RavenDb's Std input? – Ganesh R. Sep 02 '15 at 14:13
  • @GaneshR. How can you do that in MSBuild? I'm a total noob with it I'm afraid so sorry if that's a stupid question. – MarioDS Sep 02 '15 at 14:14
  • Or you can wrap RavenDBStart task into a separate process that spwans RavenDb and waits for a signal to close RavenDb? – Ganesh R. Sep 02 '15 at 14:14
  • I think you can have multiple MSBuild tasks running in parallel. So a task starts the ravenDb and waits for a signal (registry, named events etc) to close the Ravenb instance. Else just wrap RavenDB with your executable and just launch it and exit. Once you are done with RavenDB, signal your executable to close. I have not worked with MSBuild after TFS 2008 – Ganesh R. Sep 02 '15 at 14:16
  • @GaneshR. I can't find any information about custom events in MSBuild so it seems they simply don't exist. I have no idea how you could make one task wait for the other while running them in parallel. – MarioDS Sep 02 '15 at 14:19
  • http://blogs.msdn.com/b/mattdotson/archive/2006/03/03/543143.aspx I meant Named Events in C#. – Ganesh R. Sep 02 '15 at 14:25
  • @GaneshR. that is effectively polling. I appreciate your idea, but I might as well just put in a regular Thread.Sleep() in for, say, 2 seconds, which as I stated was my last resort. – MarioDS Sep 02 '15 at 14:38
  • I dont think it is polling. The example shown in the blog is for a case where the 2nd client is not sure if the handle is open. But in your case, if your first task launches your custom exe that opens the named event and waits for the event to be set / signalled, then the 2nd task will just have to open the task and set /signal the event. That way there is no polling. Anyways this is one of the ways you synchronize operations between multiple processes as is your case. – Ganesh R. Sep 02 '15 at 15:19
  • @GaneshR. I can see now, I was focussing too much on the "OpenOrWait" method from that blog post. A little worrying is that it's from 2006 so it might not work on Windows 8.1. I will try it tomorrow. – MarioDS Sep 02 '15 at 16:29

0 Answers0