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.