Fix for concurrent child processes while using pipes for IPC.

This commit is contained in:
Matthew Bowra-Dean
2011-01-04 14:23:46 +13:00
parent c8a74ef05a
commit fb8812a7fd
5 changed files with 31 additions and 15 deletions

View File

@@ -107,10 +107,11 @@ namespace OpenRA.Launcher
string[] args = e.Argument as string[]; string[] args = e.Argument as string[];
string url = args[0]; string url = args[0];
string dest = args[1]; string dest = args[1];
var p = UtilityProgram.Call("--download-url", url, dest); string pipename = UtilityProgram.GetPipeName();
var p = UtilityProgram.Call("--download-url", pipename, url, dest);
Regex r = new Regex(@"(\d{1,3})% (\d+)/(\d+) bytes"); Regex r = new Regex(@"(\d{1,3})% (\d+)/(\d+) bytes");
NamedPipeClientStream pipe = new NamedPipeClientStream(".", "OpenRA.Utility", PipeDirection.In); NamedPipeClientStream pipe = new NamedPipeClientStream(".", pipename, PipeDirection.In);
pipe.Connect(); pipe.Connect();
using (var response = new StreamReader(pipe)) using (var response = new StreamReader(pipe))
@@ -176,8 +177,9 @@ namespace OpenRA.Launcher
string zipFile = args[0]; string zipFile = args[0];
string destPath = args[1]; string destPath = args[1];
var p = UtilityProgram.CallWithAdmin("--extract-zip", zipFile, destPath); string pipename = UtilityProgram.GetPipeName();
var pipe = new NamedPipeClientStream(".", "OpenRA.Utility", PipeDirection.In); var p = UtilityProgram.CallWithAdmin("--extract-zip", pipename, zipFile, destPath);
var pipe = new NamedPipeClientStream(".", pipename, PipeDirection.In);
pipe.Connect(); pipe.Connect();

View File

@@ -150,6 +150,7 @@
this.Name = "Launcher"; this.Name = "Launcher";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "OpenRA Launcher"; this.Text = "OpenRA Launcher";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.formClosing);
this.splitContainer1.Panel1.ResumeLayout(false); this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel2.ResumeLayout(false); this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.ResumeLayout(false); this.splitContainer1.ResumeLayout(false);

View File

@@ -112,8 +112,9 @@ namespace OpenRA.Launcher
private void InstallMod(object sender, EventArgs e) private void InstallMod(object sender, EventArgs e)
{ {
if (installModDialog.ShowDialog() != DialogResult.OK) return; if (installModDialog.ShowDialog() != DialogResult.OK) return;
var p = UtilityProgram.CallWithAdmin("--extract-zip", installModDialog.FileName, ""); string pipename = UtilityProgram.GetPipeName();
var pipe = new NamedPipeClientStream(".", "OpenRA.Utility", PipeDirection.In); var p = UtilityProgram.CallWithAdmin("--extract-zip", pipename, installModDialog.FileName, "");
var pipe = new NamedPipeClientStream(".", pipename, PipeDirection.In);
pipe.Connect(); pipe.Connect();
p.WaitForExit(); p.WaitForExit();
@@ -199,5 +200,10 @@ namespace OpenRA.Launcher
else else
Renderer = "Cg"; Renderer = "Cg";
} }
void formClosing(object sender, FormClosingEventArgs e)
{
}
} }
} }

View File

@@ -56,6 +56,11 @@ namespace OpenRA.Launcher
static class UtilityProgram static class UtilityProgram
{ {
public static string GetPipeName()
{
return "OpenRA.Utility" + Guid.NewGuid().ToString();
}
static string BuildArgs(string command, string[] args) static string BuildArgs(string command, string[] args)
{ {
StringBuilder arguments = new StringBuilder(); StringBuilder arguments = new StringBuilder();
@@ -66,11 +71,11 @@ namespace OpenRA.Launcher
return arguments.ToString(); return arguments.ToString();
} }
public static Process Call(string command, params string[] args) public static Process Call(string command, string pipename, params string[] args)
{ {
Process p = new Process(); Process p = new Process();
p.StartInfo.FileName = "OpenRA.Utility.exe"; p.StartInfo.FileName = "OpenRA.Utility.exe";
p.StartInfo.Arguments = BuildArgs(command, args) + " --pipe"; p.StartInfo.Arguments = BuildArgs(command, args) + " --pipe=" + pipename;
p.StartInfo.UseShellExecute = false; p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true; p.StartInfo.CreateNoWindow = true;
@@ -81,9 +86,10 @@ namespace OpenRA.Launcher
public static string CallSimpleResponse(string command, params string[] args) public static string CallSimpleResponse(string command, params string[] args)
{ {
Call(command, args); string pipename = GetPipeName();
Call(command, pipename, args);
string responseString; string responseString;
NamedPipeClientStream pipe = new NamedPipeClientStream(".", "OpenRA.Utility", PipeDirection.In); NamedPipeClientStream pipe = new NamedPipeClientStream(".", pipename, PipeDirection.In);
pipe.Connect(); pipe.Connect();
using (var response = new StreamReader(pipe)) using (var response = new StreamReader(pipe))
{ {
@@ -93,11 +99,11 @@ namespace OpenRA.Launcher
return responseString; return responseString;
} }
public static Process CallWithAdmin(string command, params string[] args) public static Process CallWithAdmin(string command, string pipename, params string[] args)
{ {
Process p = new Process(); Process p = new Process();
p.StartInfo.FileName = "OpenRA.Utility.exe"; p.StartInfo.FileName = "OpenRA.Utility.exe";
p.StartInfo.Arguments = BuildArgs(command, args) + " --pipe"; p.StartInfo.Arguments = BuildArgs(command, args) + " --pipe=" + pipename;
p.StartInfo.Verb = "runas"; p.StartInfo.Verb = "runas";
try try

View File

@@ -46,9 +46,10 @@ namespace OpenRA.Utility
var arg = SplitArgs(args[0]); var arg = SplitArgs(args[0]);
bool piping = false; bool piping = false;
if (args.Length > 1 && args[1] == "--pipe") if (args.Length > 1 && SplitArgs(args[1]).Key == "--pipe")
{ {
piping = true; piping = true;
string pipename = SplitArgs(args[1]).Value;
NamedPipeServerStream pipe; NamedPipeServerStream pipe;
var id = WindowsIdentity.GetCurrent(); var id = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(id); var principal = new WindowsPrincipal(id);
@@ -56,10 +57,10 @@ namespace OpenRA.Utility
{ {
var ps = new PipeSecurity(); var ps = new PipeSecurity();
ps.AddAccessRule(new PipeAccessRule("EVERYONE", (PipeAccessRights)2032031, System.Security.AccessControl.AccessControlType.Allow)); ps.AddAccessRule(new PipeAccessRule("EVERYONE", (PipeAccessRights)2032031, System.Security.AccessControl.AccessControlType.Allow));
pipe = new NamedPipeServerStream("OpenRA.Utility", PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.None, 1024, 1024, ps); pipe = new NamedPipeServerStream(pipename, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.None, 1024, 1024, ps);
} }
else else
pipe = new NamedPipeServerStream("OpenRA.Utility", PipeDirection.Out); pipe = new NamedPipeServerStream(pipename, PipeDirection.Out);
pipe.WaitForConnection(); pipe.WaitForConnection();
Console.SetOut(new StreamWriter(pipe) { AutoFlush = true }); Console.SetOut(new StreamWriter(pipe) { AutoFlush = true });