private void StartRuntime(int port)
{
var psi = new ProcessStartInfo
{
FileName = Path.Combine(_runtimePath, "klr.exe"),
Arguments = String.Format(@"--appbase ""{0}"" {1} {2} {3} {4}",
Directory.GetCurrentDirectory(),
Path.Combine(_runtimePath, "lib", "Microsoft.Framework.DesignTimeHost", "Microsoft.Framework.DesignTimeHost.dll"),
port,
Process.GetCurrentProcess().Id,
_hostId),
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
UseShellExecute = false
};
var kreProcess = Process.Start(psi);
kreProcess.BeginOutputReadLine();
kreProcess.BeginErrorReadLine();
bool started = false;
ManualResetEvent wait = new ManualResetEvent(false);
string output = "";
DataReceivedEventHandler waitingForOpen = null;
waitingForOpen = (sender, e) =>
{
output += e.Data;
if(output.Contains("Listening on port " + port))
{
Volatile.Write(ref started, true);
wait.Set();
kreProcess.OutputDataReceived -= waitingForOpen;
}
};
kreProcess.OutputDataReceived += waitingForOpen;
if (kreProcess.HasExited)
throw new Exception("Error starting kre");
kreProcess.EnableRaisingEvents = true;
kreProcess.Exited += (sender, e) =>
{
wait.Set();
if (Volatile.Read(ref started))
Start();
};
wait.WaitOne();
if (!Volatile.Read(ref started))
throw new Exception("Error starting kre");
var socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
socket.Connect(new IPEndPoint(IPAddress.Loopback, port));
var networkStream = new NetworkStream(socket);
var mapping = new Dictionary<int, string>();
var queue = new ProcessingQueue(networkStream, kreProcess);
queue.OnReceive += OnReceive;
queue.Start();
_host = queue;
OnConnected(new EventArgs());
}