Reverted packaging changes from launchers.
This commit is contained in:
committed by
Paul Chote
parent
a81c865620
commit
4eaf97f90e
@@ -1,227 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace OpenRA.Launcher
|
||||
{
|
||||
public enum DownloadStatus
|
||||
{
|
||||
NOT_REGISTERED, AVAILABLE, DOWNLOADING, DOWNLOADED, EXTRACTING, EXTRACTED, ERROR
|
||||
}
|
||||
|
||||
class Download : IDisposable
|
||||
{
|
||||
DownloadStatus status = DownloadStatus.NOT_REGISTERED;
|
||||
string url = "", target = "", key = "";
|
||||
BackgroundWorker downloadBGWorker, extractBGWorker;
|
||||
int bytesTotal = 0, bytesDone = 0;
|
||||
string errorMessage = "";
|
||||
HtmlDocument document;
|
||||
|
||||
public string ErrorMessage
|
||||
{
|
||||
get { return errorMessage; }
|
||||
}
|
||||
|
||||
public int BytesDone
|
||||
{
|
||||
get { return bytesDone; }
|
||||
}
|
||||
|
||||
public int BytesTotal
|
||||
{
|
||||
get { return bytesTotal; }
|
||||
}
|
||||
|
||||
public DownloadStatus Status
|
||||
{
|
||||
get { return status; }
|
||||
}
|
||||
|
||||
public Download(HtmlDocument document, string key, string url, string filename)
|
||||
{
|
||||
this.url = url;
|
||||
this.key = key;
|
||||
this.document = document;
|
||||
target = Path.Combine(Path.GetTempPath(), filename);
|
||||
if (File.Exists(target))
|
||||
status = DownloadStatus.DOWNLOADED;
|
||||
else
|
||||
status = DownloadStatus.AVAILABLE;
|
||||
|
||||
downloadBGWorker = new BackgroundWorker()
|
||||
{
|
||||
WorkerReportsProgress = true,
|
||||
WorkerSupportsCancellation = true
|
||||
};
|
||||
|
||||
downloadBGWorker.DoWork += RunDownload;
|
||||
downloadBGWorker.ProgressChanged += UpdateProgress;
|
||||
downloadBGWorker.RunWorkerCompleted += DownloadFinished;
|
||||
|
||||
extractBGWorker = new BackgroundWorker();
|
||||
|
||||
extractBGWorker.DoWork += DoExtraction;
|
||||
extractBGWorker.RunWorkerCompleted += ExtractionFinished;
|
||||
}
|
||||
|
||||
public void StartDownload()
|
||||
{
|
||||
if (!downloadBGWorker.IsBusy)
|
||||
{
|
||||
status = DownloadStatus.DOWNLOADING;
|
||||
downloadBGWorker.RunWorkerAsync(new string[] { url, target });
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelDownload()
|
||||
{
|
||||
if (downloadBGWorker.IsBusy)
|
||||
downloadBGWorker.CancelAsync();
|
||||
}
|
||||
|
||||
public void ExtractDownload(string destPath)
|
||||
{
|
||||
if (!extractBGWorker.IsBusy)
|
||||
{
|
||||
status = DownloadStatus.EXTRACTING;
|
||||
extractBGWorker.RunWorkerAsync(new string[] { target, destPath });
|
||||
}
|
||||
}
|
||||
|
||||
static void RunDownload(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
var bgWorker = sender as BackgroundWorker;
|
||||
string[] args = e.Argument as string[];
|
||||
string url = args[0];
|
||||
string dest = args[1];
|
||||
string pipename = UtilityProgram.GetPipeName();
|
||||
var p = UtilityProgram.Call("--download-url", pipename, null, url, dest);
|
||||
Regex r = new Regex(@"(\d{1,3})% (\d+)/(\d+) bytes");
|
||||
|
||||
NamedPipeClientStream pipe = new NamedPipeClientStream(".", pipename, PipeDirection.In);
|
||||
pipe.Connect();
|
||||
|
||||
using (var response = new StreamReader(pipe))
|
||||
{
|
||||
while (!p.HasExited)
|
||||
{
|
||||
string s = response.ReadLine();
|
||||
if (string.IsNullOrEmpty(s)) continue;
|
||||
if (Util.IsError(ref s))
|
||||
throw new Exception(s);
|
||||
|
||||
if (bgWorker.CancellationPending)
|
||||
{
|
||||
e.Cancel = true;
|
||||
p.Kill();
|
||||
return;
|
||||
}
|
||||
if (!r.IsMatch(s)) continue;
|
||||
var m = r.Match(s);
|
||||
bgWorker.ReportProgress(int.Parse(m.Groups[1].Value),
|
||||
new string[] { m.Groups[2].Value, m.Groups[3].Value });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateProgress(object sender, ProgressChangedEventArgs e)
|
||||
{
|
||||
string[] s = e.UserState as string[];
|
||||
bytesDone = int.Parse(s[0]);
|
||||
bytesTotal = int.Parse(s[1]);
|
||||
document.InvokeScript("downloadProgressed", new object[] { key });
|
||||
}
|
||||
|
||||
void DownloadFinished(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
if (e.Error != null)
|
||||
{
|
||||
status = DownloadStatus.ERROR;
|
||||
errorMessage = e.Error.Message;
|
||||
//if (File.Exists(target))
|
||||
// File.Delete(target);
|
||||
document.InvokeScript("downloadProgressed", new object[] { key });
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Cancelled)
|
||||
{
|
||||
status = DownloadStatus.ERROR;
|
||||
errorMessage = "Download Cancelled";
|
||||
//if (File.Exists(target))
|
||||
// File.Delete(target);
|
||||
document.InvokeScript("downloadProgressed", new object[] { key });
|
||||
return;
|
||||
}
|
||||
|
||||
status = DownloadStatus.DOWNLOADED;
|
||||
document.InvokeScript("downloadProgressed", new object[] { key });
|
||||
}
|
||||
|
||||
void DoExtraction(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
string[] args = e.Argument as string[];
|
||||
string zipFile = args[0];
|
||||
string destPath = args[1];
|
||||
|
||||
string pipename = UtilityProgram.GetPipeName();
|
||||
var p = UtilityProgram.CallWithAdmin("--extract-zip", pipename, zipFile, destPath);
|
||||
var pipe = new NamedPipeClientStream(".", pipename, PipeDirection.In);
|
||||
|
||||
pipe.Connect();
|
||||
|
||||
using (var reader = new StreamReader(pipe))
|
||||
{
|
||||
while (!p.HasExited)
|
||||
{
|
||||
string s = reader.ReadLine();
|
||||
if (string.IsNullOrEmpty(s)) continue;
|
||||
if (Util.IsError(ref s))
|
||||
throw new Exception(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExtractionFinished(object sender, RunWorkerCompletedEventArgs e)
|
||||
{
|
||||
if (e.Error != null)
|
||||
{
|
||||
status = DownloadStatus.ERROR;
|
||||
errorMessage = e.Error.Message;
|
||||
document.InvokeScript("extractProgressed", new object[] { key });
|
||||
}
|
||||
|
||||
|
||||
status = DownloadStatus.EXTRACTED;
|
||||
document.InvokeScript("extractProgressed", new object[] { key });
|
||||
}
|
||||
|
||||
bool disposed = false;
|
||||
|
||||
~Download()
|
||||
{
|
||||
if (!disposed)
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (status == DownloadStatus.DOWNLOADING && File.Exists(target))
|
||||
File.Delete(target);
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace OpenRA.Launcher
|
||||
{
|
||||
public class JSBridge
|
||||
{
|
||||
Dictionary<string, Mod> allMods = new Dictionary<string,Mod>();
|
||||
|
||||
public Dictionary<string, Mod> AllMods
|
||||
{
|
||||
get { return allMods; }
|
||||
set { allMods = value; }
|
||||
}
|
||||
Dictionary<string, Download> downloads = new Dictionary<string,Download>();
|
||||
|
||||
readonly Control hostControl;
|
||||
HtmlDocument document = null;
|
||||
|
||||
public JSBridge(Control hostControl)
|
||||
{
|
||||
this.hostControl = hostControl;
|
||||
}
|
||||
|
||||
public HtmlDocument Document
|
||||
{
|
||||
get { return document; }
|
||||
set { document = value; }
|
||||
}
|
||||
|
||||
public bool existsInMod(string file, string mod)
|
||||
{
|
||||
string cleanedPath = CleanPath(file);
|
||||
return File.Exists(string.Format("mods{0}{1}{0}{2}", Path.DirectorySeparatorChar, mod, cleanedPath));
|
||||
}
|
||||
|
||||
public void log(string message)
|
||||
{
|
||||
Console.WriteLine("js: " + message);
|
||||
}
|
||||
|
||||
public bool launchMod(string mod)
|
||||
{
|
||||
string m = mod;
|
||||
List<string> modList = new List<string>();
|
||||
modList.Add(m);
|
||||
if (!allMods.ContainsKey(m))
|
||||
{
|
||||
MessageBox.Show("allMods does not contain " + m);
|
||||
return false;
|
||||
}
|
||||
while (!string.IsNullOrEmpty(allMods[m].Requires))
|
||||
{
|
||||
m = allMods[m].Requires;
|
||||
modList.Add(m);
|
||||
}
|
||||
|
||||
Process p = new Process();
|
||||
p.StartInfo.FileName = "OpenRA.Game.exe";
|
||||
p.StartInfo.Arguments = "Game.Mods=" + string.Join(",", modList.ToArray());
|
||||
p.StartInfo.Arguments += " Graphics.Renderer=" + Launcher.Renderer;
|
||||
p.Start();
|
||||
return true;
|
||||
}
|
||||
|
||||
Regex p = new Regex(@"\.\.[/\\]?");
|
||||
string CleanPath(string path)
|
||||
{
|
||||
string root = Path.GetPathRoot(path);
|
||||
string cleanedPath = path.Remove(0, root.Length);
|
||||
return p.Replace(cleanedPath, "");
|
||||
}
|
||||
|
||||
public void registerDownload(string key, string url, string filename)
|
||||
{
|
||||
string cleanedPath = CleanPath(filename);
|
||||
if (!downloads.ContainsKey(key))
|
||||
downloads.Add(key, new Download(document, key, url, cleanedPath));
|
||||
else
|
||||
downloads[key] = new Download(document, key, url, cleanedPath);
|
||||
}
|
||||
|
||||
public bool startDownload(string key)
|
||||
{
|
||||
if (!downloads.ContainsKey(key))
|
||||
return false;
|
||||
|
||||
downloads[key].StartDownload();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool cancelDownload(string key)
|
||||
{
|
||||
if (!downloads.ContainsKey(key))
|
||||
return false;
|
||||
|
||||
downloads[key].CancelDownload();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public string downloadStatus(string key)
|
||||
{
|
||||
if (!downloads.ContainsKey(key))
|
||||
return DownloadStatus.NOT_REGISTERED.ToString();
|
||||
|
||||
return downloads[key].Status.ToString();
|
||||
}
|
||||
|
||||
public string downloadError(string key)
|
||||
{
|
||||
if (!downloads.ContainsKey(key))
|
||||
return "";
|
||||
|
||||
return downloads[key].ErrorMessage;
|
||||
}
|
||||
|
||||
public int bytesCompleted(string key)
|
||||
{
|
||||
if (!downloads.ContainsKey(key))
|
||||
return -1;
|
||||
|
||||
return downloads[key].BytesDone;
|
||||
}
|
||||
|
||||
public int bytesTotal(string key)
|
||||
{
|
||||
if (!downloads.ContainsKey(key))
|
||||
return -1;
|
||||
|
||||
return downloads[key].BytesTotal;
|
||||
}
|
||||
|
||||
public bool extractDownload(string key, string targetDir, string mod)
|
||||
{
|
||||
string cleanedPath = CleanPath(targetDir);
|
||||
|
||||
string targetPath = Path.Combine(mod, cleanedPath);
|
||||
|
||||
if (!downloads.ContainsKey(key))
|
||||
return false;
|
||||
|
||||
if (downloads[key].Status != DownloadStatus.DOWNLOADED)
|
||||
return false;
|
||||
|
||||
downloads[key].ExtractDownload(targetPath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public string metadata(string field, string mod)
|
||||
{
|
||||
if (field == "VERSION")
|
||||
return allMods[mod].Version;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public void httpRequest(string url, string callbackName)
|
||||
{
|
||||
string pipename = UtilityProgram.GetPipeName();
|
||||
var pipe = new NamedPipeClientStream(".", pipename, PipeDirection.In);
|
||||
|
||||
var p = UtilityProgram.Call("--download-url", pipename,
|
||||
(_, e) =>
|
||||
{
|
||||
using (var reader = new StreamReader(pipe))
|
||||
{
|
||||
var data = reader.ReadToEnd();
|
||||
hostControl.Invoke((Delegate)(Action)(() =>
|
||||
document.InvokeScript(callbackName, new object[] { data })));
|
||||
}
|
||||
}, url);
|
||||
|
||||
pipe.Connect();
|
||||
}
|
||||
}
|
||||
}
|
||||
174
OpenRA.Launcher/Launcher.Designer.cs
generated
174
OpenRA.Launcher/Launcher.Designer.cs
generated
@@ -1,174 +0,0 @@
|
||||
namespace OpenRA.Launcher
|
||||
{
|
||||
partial class Launcher
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.Windows.Forms.TreeNode treeNode1 = new System.Windows.Forms.TreeNode("Mods", -2, -2);
|
||||
this.installButton = new System.Windows.Forms.Button();
|
||||
this.installModDialog = new System.Windows.Forms.OpenFileDialog();
|
||||
this.treeView = new System.Windows.Forms.TreeView();
|
||||
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
|
||||
this.webBrowser = new System.Windows.Forms.WebBrowser();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.cgButton = new System.Windows.Forms.RadioButton();
|
||||
this.glButton = new System.Windows.Forms.RadioButton();
|
||||
this.splitContainer1.Panel1.SuspendLayout();
|
||||
this.splitContainer1.Panel2.SuspendLayout();
|
||||
this.splitContainer1.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// installButton
|
||||
//
|
||||
this.installButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.installButton.Location = new System.Drawing.Point(12, 12);
|
||||
this.installButton.Name = "installButton";
|
||||
this.installButton.Size = new System.Drawing.Size(116, 23);
|
||||
this.installButton.TabIndex = 2;
|
||||
this.installButton.Text = "Install Mod...";
|
||||
this.installButton.UseVisualStyleBackColor = true;
|
||||
this.installButton.Click += new System.EventHandler(this.InstallMod);
|
||||
//
|
||||
// installModDialog
|
||||
//
|
||||
this.installModDialog.Filter = "Zip files|*.zip";
|
||||
this.installModDialog.RestoreDirectory = true;
|
||||
//
|
||||
// treeView
|
||||
//
|
||||
this.treeView.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.treeView.Location = new System.Drawing.Point(0, 0);
|
||||
this.treeView.Name = "treeView";
|
||||
treeNode1.ImageIndex = -2;
|
||||
treeNode1.Name = "ModsNode";
|
||||
treeNode1.SelectedImageIndex = -2;
|
||||
treeNode1.Text = "Mods";
|
||||
this.treeView.Nodes.AddRange(new System.Windows.Forms.TreeNode[] {
|
||||
treeNode1});
|
||||
this.treeView.ShowLines = false;
|
||||
this.treeView.Size = new System.Drawing.Size(160, 465);
|
||||
this.treeView.TabIndex = 3;
|
||||
this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeView_AfterSelect);
|
||||
//
|
||||
// splitContainer1
|
||||
//
|
||||
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
|
||||
this.splitContainer1.Name = "splitContainer1";
|
||||
//
|
||||
// splitContainer1.Panel1
|
||||
//
|
||||
this.splitContainer1.Panel1.Controls.Add(this.treeView);
|
||||
//
|
||||
// splitContainer1.Panel2
|
||||
//
|
||||
this.splitContainer1.Panel2.Controls.Add(this.webBrowser);
|
||||
this.splitContainer1.Size = new System.Drawing.Size(671, 465);
|
||||
this.splitContainer1.SplitterDistance = 160;
|
||||
this.splitContainer1.TabIndex = 4;
|
||||
//
|
||||
// webBrowser
|
||||
//
|
||||
this.webBrowser.AllowWebBrowserDrop = false;
|
||||
this.webBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.webBrowser.Location = new System.Drawing.Point(0, 0);
|
||||
this.webBrowser.MinimumSize = new System.Drawing.Size(20, 20);
|
||||
this.webBrowser.Name = "webBrowser";
|
||||
this.webBrowser.ScrollBarsEnabled = false;
|
||||
this.webBrowser.Size = new System.Drawing.Size(507, 465);
|
||||
this.webBrowser.TabIndex = 0;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.cgButton);
|
||||
this.panel1.Controls.Add(this.glButton);
|
||||
this.panel1.Controls.Add(this.installButton);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.panel1.Location = new System.Drawing.Point(0, 465);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(671, 47);
|
||||
this.panel1.TabIndex = 5;
|
||||
//
|
||||
// cgButton
|
||||
//
|
||||
this.cgButton.AutoSize = true;
|
||||
this.cgButton.Location = new System.Drawing.Point(481, 18);
|
||||
this.cgButton.Name = "cgButton";
|
||||
this.cgButton.Size = new System.Drawing.Size(87, 17);
|
||||
this.cgButton.TabIndex = 4;
|
||||
this.cgButton.TabStop = true;
|
||||
this.cgButton.Text = "CG Renderer";
|
||||
this.cgButton.UseVisualStyleBackColor = true;
|
||||
this.cgButton.CheckedChanged += new System.EventHandler(this.rendererChanged);
|
||||
//
|
||||
// glButton
|
||||
//
|
||||
this.glButton.AutoSize = true;
|
||||
this.glButton.Location = new System.Drawing.Point(574, 18);
|
||||
this.glButton.Name = "glButton";
|
||||
this.glButton.Size = new System.Drawing.Size(86, 17);
|
||||
this.glButton.TabIndex = 3;
|
||||
this.glButton.TabStop = true;
|
||||
this.glButton.Text = "GL Renderer";
|
||||
this.glButton.UseVisualStyleBackColor = true;
|
||||
this.glButton.CheckedChanged += new System.EventHandler(this.rendererChanged);
|
||||
//
|
||||
// Launcher
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(671, 512);
|
||||
this.Controls.Add(this.splitContainer1);
|
||||
this.Controls.Add(this.panel1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
this.MaximizeBox = false;
|
||||
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);
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button installButton;
|
||||
private System.Windows.Forms.OpenFileDialog installModDialog;
|
||||
private System.Windows.Forms.TreeView treeView;
|
||||
private System.Windows.Forms.SplitContainer splitContainer1;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.WebBrowser webBrowser;
|
||||
private System.Windows.Forms.RadioButton cgButton;
|
||||
private System.Windows.Forms.RadioButton glButton;
|
||||
}
|
||||
}
|
||||
@@ -1,209 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using System.IO.Pipes;
|
||||
using System.IO;
|
||||
|
||||
namespace OpenRA.Launcher
|
||||
{
|
||||
public partial class Launcher : Form
|
||||
{
|
||||
Dictionary<string, Mod> allMods;
|
||||
public static string Renderer = "Gl";
|
||||
static string SupportDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + Path.DirectorySeparatorChar + "OpenRA";
|
||||
|
||||
public Launcher()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Util.UacShield(installButton);
|
||||
|
||||
webBrowser.ObjectForScripting = new JSBridge(this);
|
||||
webBrowser.DocumentCompleted += (o, e) =>
|
||||
{
|
||||
var b = o as WebBrowser;
|
||||
(b.ObjectForScripting as JSBridge).Document = b.Document;
|
||||
};
|
||||
RefreshMods();
|
||||
string response = UtilityProgram.CallSimpleResponse("--settings-value", SupportDir, "Graphics.Renderer");
|
||||
if (Util.IsError(ref response) || response.Equals("gl", StringComparison.InvariantCultureIgnoreCase))
|
||||
glButton.Checked = true;
|
||||
else
|
||||
cgButton.Checked = true;
|
||||
}
|
||||
|
||||
Mod GetMetadata(string mod)
|
||||
{
|
||||
string responseString = UtilityProgram.CallSimpleResponse("-i", mod);
|
||||
|
||||
if (Util.IsError(ref responseString)) return null;
|
||||
string[] lines = responseString.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
lines[i] = lines[i].Trim('\r');
|
||||
|
||||
string title = "", version = "", author = "", description = "", requires = "";
|
||||
bool standalone = false;
|
||||
foreach (string line in lines)
|
||||
{
|
||||
string s = line.Trim(' ', '\r', '\n');
|
||||
int i = s.IndexOf(':');
|
||||
if (i + 2 > s.Length) continue;
|
||||
string value = s.Substring(i + 2);
|
||||
switch (s.Substring(0, i))
|
||||
{
|
||||
case "Title":
|
||||
title = value;
|
||||
break;
|
||||
case "Version":
|
||||
version = value;
|
||||
break;
|
||||
case "Author":
|
||||
author = value;
|
||||
break;
|
||||
case "Description":
|
||||
description = value;
|
||||
break;
|
||||
case "Requires":
|
||||
requires = value;
|
||||
break;
|
||||
case "Standalone":
|
||||
standalone = bool.Parse(value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new Mod(title, version, author, description, requires, standalone);
|
||||
}
|
||||
|
||||
void RefreshMods()
|
||||
{
|
||||
string responseString = UtilityProgram.CallSimpleResponse("--list-mods");
|
||||
|
||||
string[] mods;
|
||||
if (!Util.IsError(ref responseString))
|
||||
mods = responseString.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
else
|
||||
throw new Exception(string.Format("Could not list mods: {0}", responseString));
|
||||
|
||||
for (int i = 0; i < mods.Length; i++)
|
||||
mods[i] = mods[i].Trim('\r');
|
||||
|
||||
allMods = mods.ToDictionary(x => x, x => GetMetadata(x));
|
||||
|
||||
(webBrowser.ObjectForScripting as JSBridge).AllMods = allMods;
|
||||
|
||||
RefreshModTree(treeView, allMods.Keys.ToArray());
|
||||
}
|
||||
|
||||
private void InstallMod(object sender, EventArgs e)
|
||||
{
|
||||
if (installModDialog.ShowDialog() != DialogResult.OK) return;
|
||||
string pipename = UtilityProgram.GetPipeName();
|
||||
var p = UtilityProgram.CallWithAdmin("--extract-zip", pipename, installModDialog.FileName, "");
|
||||
var pipe = new NamedPipeClientStream(".", pipename, PipeDirection.In);
|
||||
pipe.Connect();
|
||||
|
||||
p.WaitForExit();
|
||||
|
||||
using (var response = new StreamReader(pipe))
|
||||
{
|
||||
response.ReadToEnd();
|
||||
}
|
||||
|
||||
RefreshMods();
|
||||
}
|
||||
|
||||
void RefreshModTree(TreeView treeView, string[] modList)
|
||||
{
|
||||
treeView.Nodes["ModsNode"].Nodes.Clear();
|
||||
Dictionary<string, TreeNode> nodes;
|
||||
nodes = modList.Where(x => allMods[x].Standalone).ToDictionary(x => x,
|
||||
x => new TreeNode(allMods[x].Title) { Name = x });
|
||||
string[] rootMods = modList.Where(x => allMods[x].Standalone).ToArray();
|
||||
Stack<string> remaining = new Stack<string>(modList.Except(nodes.Keys));
|
||||
|
||||
bool progress = true;
|
||||
while (remaining.Count > 0 && progress)
|
||||
{
|
||||
progress = false;
|
||||
string s = remaining.Pop();
|
||||
var n = new TreeNode(allMods[s].Title) { Name = s };
|
||||
if (allMods[s].Requires == null) { remaining.Push(s); continue; }
|
||||
if (!nodes.ContainsKey(allMods[s].Requires)) { remaining.Push(s); continue; }
|
||||
nodes[allMods[s].Requires].Nodes.Add(n);
|
||||
nodes.Add(s, n);
|
||||
progress = true;
|
||||
}
|
||||
|
||||
foreach (string s in rootMods)
|
||||
treeView.Nodes["ModsNode"].Nodes.Add(nodes[s]);
|
||||
|
||||
if (remaining.Count > 0)
|
||||
{
|
||||
var unspecified = new TreeNode("<Unspecified Dependency>") { ForeColor = SystemColors.GrayText };
|
||||
var missing = new TreeNode("<Missing Dependency>") { ForeColor = SystemColors.GrayText };
|
||||
|
||||
foreach (var s in remaining)
|
||||
{
|
||||
if (allMods[s].Requires == null)
|
||||
unspecified.Nodes.Add(new TreeNode(allMods[s].Title)
|
||||
{ ForeColor = SystemColors.GrayText, Name = s });
|
||||
else if (!nodes.ContainsKey(allMods[s].Requires))
|
||||
missing.Nodes.Add(new TreeNode(allMods[s].Title)
|
||||
{ ForeColor = SystemColors.GrayText, Name = s });
|
||||
}
|
||||
string brokenKey = "BrokenModsNode";
|
||||
if (treeView.Nodes[brokenKey] != null)
|
||||
treeView.Nodes.RemoveByKey(brokenKey);
|
||||
treeView.Nodes.Add(brokenKey, "Broken Mods");
|
||||
treeView.Nodes[brokenKey].Nodes.Add(unspecified);
|
||||
treeView.Nodes[brokenKey].Nodes.Add(missing);
|
||||
}
|
||||
treeView.Nodes["ModsNode"].ExpandAll();
|
||||
treeView.Invalidate();
|
||||
|
||||
string responseString = UtilityProgram.CallSimpleResponse("--settings-value", SupportDir, "Game.Mods");
|
||||
|
||||
if (Util.IsError(ref responseString))
|
||||
treeView.SelectedNode = treeView.Nodes["ModsNode"].Nodes["ra"];
|
||||
else
|
||||
treeView.SelectedNode = treeView.Nodes["ModsNode"].Nodes[responseString];
|
||||
}
|
||||
|
||||
void treeView_AfterSelect(object sender, TreeViewEventArgs e)
|
||||
{
|
||||
Mod selectedMod;
|
||||
if (!allMods.TryGetValue(e.Node.Name, out selectedMod)) return;
|
||||
string modHtmlPath = string.Format("mods{0}{1}{0}mod.html", Path.DirectorySeparatorChar, e.Node.Name);
|
||||
if (!File.Exists(modHtmlPath)) return;
|
||||
webBrowser.Navigate(Path.GetFullPath(modHtmlPath));
|
||||
}
|
||||
|
||||
private void rendererChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (sender == glButton)
|
||||
Renderer = "Gl";
|
||||
else
|
||||
Renderer = "Cg";
|
||||
}
|
||||
|
||||
void formClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="installModDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -1,33 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
using System;
|
||||
|
||||
namespace OpenRA.Launcher
|
||||
{
|
||||
public class Mod
|
||||
{
|
||||
public string Title { get; private set; }
|
||||
public string Version { get; private set; }
|
||||
public string Author { get; private set; }
|
||||
public string Description { get; private set; }
|
||||
public string Requires { get; private set; }
|
||||
public bool Standalone { get; private set; }
|
||||
|
||||
public Mod(string title, string version, string author, string description, string requires, bool standalone)
|
||||
{
|
||||
Title = title;
|
||||
Version = version;
|
||||
Author = author;
|
||||
Description = description;
|
||||
Requires = requires;
|
||||
Standalone = standalone;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{2EA6C9C7-28A8-46C6-A42C-9275692EB285}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>OpenRA.Launcher</RootNamespace>
|
||||
<AssemblyName>OpenRA.Launcher</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<StartupObject>
|
||||
</StartupObject>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<ItemGroup>
|
||||
<Compile Include="Download.cs" />
|
||||
<Compile Include="JSBridge.cs" />
|
||||
<Compile Include="Launcher.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Launcher.Designer.cs">
|
||||
<DependentUpon>Launcher.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Mod.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Util.cs" />
|
||||
<Compile Include="UtilityProgram.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Launcher.resx">
|
||||
<DependentUpon>Launcher.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,26 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace OpenRA.Launcher
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new Launcher());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace OpenRA.Launcher
|
||||
{
|
||||
static class Util
|
||||
{
|
||||
[DllImport("user32")]
|
||||
public static extern UInt32 SendMessage
|
||||
(IntPtr hWnd, UInt32 msg, UInt32 wParam, UInt32 lParam);
|
||||
|
||||
internal const int BCM_FIRST = 0x1600; //Normal button
|
||||
|
||||
internal const int BCM_SETSHIELD = (BCM_FIRST + 0x000C); //Elevated button
|
||||
|
||||
static public void UacShield(Button b)
|
||||
{
|
||||
b.FlatStyle = FlatStyle.System;
|
||||
SendMessage(b.Handle, BCM_SETSHIELD, 0, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
static public bool IsError(ref string utilityResponseLine)
|
||||
{
|
||||
utilityResponseLine = utilityResponseLine.Trim('\r', '\n');
|
||||
if (utilityResponseLine.StartsWith("Error:"))
|
||||
{
|
||||
utilityResponseLine = utilityResponseLine.Remove(0, 7);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see LICENSE.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenRA.Launcher
|
||||
{
|
||||
class UtilityProgramResponse
|
||||
{
|
||||
public bool IsError
|
||||
{
|
||||
get { return response.StartsWith("Error:"); }
|
||||
}
|
||||
|
||||
string response;
|
||||
|
||||
public string Response
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsError)
|
||||
return response.Remove(0, 7);
|
||||
else
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] ResponseLines
|
||||
{
|
||||
get
|
||||
{
|
||||
string s = response;
|
||||
if (IsError)
|
||||
s = response.Remove(0, 7);
|
||||
return s.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
|
||||
public UtilityProgramResponse(string response)
|
||||
{
|
||||
this.response = response.Trim('\r', '\n');
|
||||
}
|
||||
}
|
||||
|
||||
static class UtilityProgram
|
||||
{
|
||||
public static string GetPipeName()
|
||||
{
|
||||
return "OpenRA.Utility" + Guid.NewGuid().ToString();
|
||||
}
|
||||
|
||||
static string BuildArgs(string command, string[] args)
|
||||
{
|
||||
StringBuilder arguments = new StringBuilder();
|
||||
arguments.Append("\"");
|
||||
arguments.Append(command + "=");
|
||||
arguments.Append(string.Join(",", args));
|
||||
arguments.Append("\"");
|
||||
return arguments.ToString();
|
||||
}
|
||||
|
||||
public static Process Call(string command, string pipename, EventHandler onExit, params string[] args)
|
||||
{
|
||||
Process p = new Process();
|
||||
p.StartInfo.FileName = "OpenRA.Utility.exe";
|
||||
p.StartInfo.Arguments = BuildArgs(command, args) + " --pipe=" + pipename;
|
||||
p.StartInfo.UseShellExecute = false;
|
||||
p.StartInfo.CreateNoWindow = true;
|
||||
|
||||
if (onExit != null)
|
||||
{
|
||||
p.EnableRaisingEvents = true;
|
||||
p.Exited += onExit;
|
||||
}
|
||||
|
||||
p.Start();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
public static string CallSimpleResponse(string command, params string[] args)
|
||||
{
|
||||
string pipename = GetPipeName();
|
||||
Call(command, pipename, null, args);
|
||||
string responseString;
|
||||
NamedPipeClientStream pipe = new NamedPipeClientStream(".", pipename, PipeDirection.In);
|
||||
pipe.Connect();
|
||||
using (var response = new StreamReader(pipe))
|
||||
{
|
||||
responseString = response.ReadToEnd();
|
||||
}
|
||||
|
||||
return responseString;
|
||||
}
|
||||
|
||||
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=" + pipename;
|
||||
p.StartInfo.Verb = "runas";
|
||||
|
||||
try
|
||||
{
|
||||
p.Start();
|
||||
}
|
||||
catch (Win32Exception e)
|
||||
{
|
||||
if (e.NativeErrorCode == 1223) //ERROR_CANCELLED
|
||||
return null;
|
||||
throw e;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user