From fb8812a7fd65d4e82876f031b4282449ef922383 Mon Sep 17 00:00:00 2001 From: Matthew Bowra-Dean Date: Tue, 4 Jan 2011 14:23:46 +1300 Subject: [PATCH] Fix for concurrent child processes while using pipes for IPC. --- OpenRA.Launcher/Download.cs | 10 ++++++---- OpenRA.Launcher/Launcher.Designer.cs | 1 + OpenRA.Launcher/Launcher.cs | 10 ++++++++-- OpenRA.Launcher/UtilityProgram.cs | 18 ++++++++++++------ OpenRA.Utility/Program.cs | 7 ++++--- 5 files changed, 31 insertions(+), 15 deletions(-) diff --git a/OpenRA.Launcher/Download.cs b/OpenRA.Launcher/Download.cs index d1957f9b4c..9478d8ecd5 100644 --- a/OpenRA.Launcher/Download.cs +++ b/OpenRA.Launcher/Download.cs @@ -107,10 +107,11 @@ namespace OpenRA.Launcher string[] args = e.Argument as string[]; string url = args[0]; 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"); - NamedPipeClientStream pipe = new NamedPipeClientStream(".", "OpenRA.Utility", PipeDirection.In); + NamedPipeClientStream pipe = new NamedPipeClientStream(".", pipename, PipeDirection.In); pipe.Connect(); using (var response = new StreamReader(pipe)) @@ -176,8 +177,9 @@ namespace OpenRA.Launcher string zipFile = args[0]; string destPath = args[1]; - var p = UtilityProgram.CallWithAdmin("--extract-zip", zipFile, destPath); - var pipe = new NamedPipeClientStream(".", "OpenRA.Utility", PipeDirection.In); + string pipename = UtilityProgram.GetPipeName(); + var p = UtilityProgram.CallWithAdmin("--extract-zip", pipename, zipFile, destPath); + var pipe = new NamedPipeClientStream(".", pipename, PipeDirection.In); pipe.Connect(); diff --git a/OpenRA.Launcher/Launcher.Designer.cs b/OpenRA.Launcher/Launcher.Designer.cs index 0a29a7ef64..10c82e3867 100644 --- a/OpenRA.Launcher/Launcher.Designer.cs +++ b/OpenRA.Launcher/Launcher.Designer.cs @@ -150,6 +150,7 @@ this.Name = "Launcher"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "OpenRA Launcher"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.formClosing); this.splitContainer1.Panel1.ResumeLayout(false); this.splitContainer1.Panel2.ResumeLayout(false); this.splitContainer1.ResumeLayout(false); diff --git a/OpenRA.Launcher/Launcher.cs b/OpenRA.Launcher/Launcher.cs index 30e3c7bdfb..756dc91add 100644 --- a/OpenRA.Launcher/Launcher.cs +++ b/OpenRA.Launcher/Launcher.cs @@ -112,8 +112,9 @@ namespace OpenRA.Launcher private void InstallMod(object sender, EventArgs e) { if (installModDialog.ShowDialog() != DialogResult.OK) return; - var p = UtilityProgram.CallWithAdmin("--extract-zip", installModDialog.FileName, ""); - var pipe = new NamedPipeClientStream(".", "OpenRA.Utility", PipeDirection.In); + string pipename = UtilityProgram.GetPipeName(); + var p = UtilityProgram.CallWithAdmin("--extract-zip", pipename, installModDialog.FileName, ""); + var pipe = new NamedPipeClientStream(".", pipename, PipeDirection.In); pipe.Connect(); p.WaitForExit(); @@ -199,5 +200,10 @@ namespace OpenRA.Launcher else Renderer = "Cg"; } + + void formClosing(object sender, FormClosingEventArgs e) + { + + } } } diff --git a/OpenRA.Launcher/UtilityProgram.cs b/OpenRA.Launcher/UtilityProgram.cs index 0c5fd70353..e62fe057c6 100644 --- a/OpenRA.Launcher/UtilityProgram.cs +++ b/OpenRA.Launcher/UtilityProgram.cs @@ -56,6 +56,11 @@ namespace OpenRA.Launcher static class UtilityProgram { + public static string GetPipeName() + { + return "OpenRA.Utility" + Guid.NewGuid().ToString(); + } + static string BuildArgs(string command, string[] args) { StringBuilder arguments = new StringBuilder(); @@ -66,11 +71,11 @@ namespace OpenRA.Launcher 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(); 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.CreateNoWindow = true; @@ -81,9 +86,10 @@ namespace OpenRA.Launcher public static string CallSimpleResponse(string command, params string[] args) { - Call(command, args); + string pipename = GetPipeName(); + Call(command, pipename, args); string responseString; - NamedPipeClientStream pipe = new NamedPipeClientStream(".", "OpenRA.Utility", PipeDirection.In); + NamedPipeClientStream pipe = new NamedPipeClientStream(".", pipename, PipeDirection.In); pipe.Connect(); using (var response = new StreamReader(pipe)) { @@ -93,11 +99,11 @@ namespace OpenRA.Launcher 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(); 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"; try diff --git a/OpenRA.Utility/Program.cs b/OpenRA.Utility/Program.cs index ccaf377137..a05373ef59 100644 --- a/OpenRA.Utility/Program.cs +++ b/OpenRA.Utility/Program.cs @@ -46,9 +46,10 @@ namespace OpenRA.Utility var arg = SplitArgs(args[0]); bool piping = false; - if (args.Length > 1 && args[1] == "--pipe") + if (args.Length > 1 && SplitArgs(args[1]).Key == "--pipe") { piping = true; + string pipename = SplitArgs(args[1]).Value; NamedPipeServerStream pipe; var id = WindowsIdentity.GetCurrent(); var principal = new WindowsPrincipal(id); @@ -56,10 +57,10 @@ namespace OpenRA.Utility { var ps = new PipeSecurity(); 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 - pipe = new NamedPipeServerStream("OpenRA.Utility", PipeDirection.Out); + pipe = new NamedPipeServerStream(pipename, PipeDirection.Out); pipe.WaitForConnection(); Console.SetOut(new StreamWriter(pipe) { AutoFlush = true });