├── .gitignore ├── LICENSE ├── OpenRoC ├── AboutDialog.Designer.cs ├── AboutDialog.cs ├── AboutDialog.resx ├── App.config ├── Docs │ ├── main.png │ ├── process.png │ └── settings.png ├── Extensions.cs ├── FodyWeavers.xml ├── Logger.cs ├── LogsDialog.Designer.cs ├── LogsDialog.cs ├── LogsDialog.resx ├── MainDialog.Designer.cs ├── MainDialog.cs ├── MainDialog.resx ├── Metrics │ ├── Collector.cs │ ├── CpuCollector.cs │ ├── GpuCollector.cs │ ├── Manager.cs │ └── RamCollector.cs ├── OpenRoC.csproj ├── OpenRoC.sln ├── ProcessDialog.Designer.cs ├── ProcessDialog.cs ├── ProcessDialog.resx ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Resources │ └── OpenRoc.xml ├── SensuInterface.cs ├── Settings.cs ├── SettingsDialog.Designer.cs ├── SettingsDialog.cs ├── SettingsDialog.resx ├── packages.config ├── phoenix.ico └── testProcessWindowed │ ├── App.config │ ├── MainForm.Designer.cs │ ├── MainForm.cs │ ├── MainForm.resx │ ├── Program.cs │ ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings │ └── testProcessWindowed.csproj ├── README.md ├── libOpenRoC ├── ExecutorService.cs ├── Extensions.cs ├── NativeMethods.cs ├── ProcessHelper.cs ├── ProcessManager.cs ├── ProcessObserver.cs ├── ProcessOptions.cs ├── ProcessRunner.cs ├── Properties │ └── AssemblyInfo.cs └── libOpenRoC.csproj └── testOpenRoC ├── .gitignore ├── ExecutorServiceUnitTests.cs ├── ProcessManagerUnitTests.cs ├── ProcessOptionsUnitTests.cs ├── ProcessRunnerUnitTests.cs ├── Properties └── AssemblyInfo.cs └── testOpenRoC.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Helios Interactive 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /OpenRoC/AboutDialog.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace oroc 2 | { 3 | partial class AboutDialog 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutDialog)); 32 | this.AboutRichTextBox = new System.Windows.Forms.RichTextBox(); 33 | this.title = new System.Windows.Forms.Label(); 34 | this.caption = new System.Windows.Forms.Label(); 35 | this.SuspendLayout(); 36 | // 37 | // AboutRichTextBox 38 | // 39 | this.AboutRichTextBox.BackColor = System.Drawing.SystemColors.Control; 40 | this.AboutRichTextBox.BorderStyle = System.Windows.Forms.BorderStyle.None; 41 | this.AboutRichTextBox.Location = new System.Drawing.Point(12, 115); 42 | this.AboutRichTextBox.Name = "AboutRichTextBox"; 43 | this.AboutRichTextBox.ReadOnly = true; 44 | this.AboutRichTextBox.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.None; 45 | this.AboutRichTextBox.Size = new System.Drawing.Size(528, 170); 46 | this.AboutRichTextBox.TabIndex = 0; 47 | this.AboutRichTextBox.TabStop = false; 48 | this.AboutRichTextBox.Text = resources.GetString("AboutRichTextBox.Text"); 49 | this.AboutRichTextBox.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.OnAboutRichTextBoxLinkClicked); 50 | // 51 | // title 52 | // 53 | this.title.Dock = System.Windows.Forms.DockStyle.Top; 54 | this.title.Font = new System.Drawing.Font("Microsoft Sans Serif", 27.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 55 | this.title.Location = new System.Drawing.Point(0, 0); 56 | this.title.Name = "title"; 57 | this.title.Size = new System.Drawing.Size(552, 64); 58 | this.title.TabIndex = 1; 59 | this.title.Text = "OpenRoC"; 60 | this.title.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 61 | // 62 | // caption 63 | // 64 | this.caption.Dock = System.Windows.Forms.DockStyle.Top; 65 | this.caption.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 66 | this.caption.Location = new System.Drawing.Point(0, 64); 67 | this.caption.Name = "caption"; 68 | this.caption.Size = new System.Drawing.Size(552, 39); 69 | this.caption.TabIndex = 2; 70 | this.caption.Text = "Open-source Restart on Crash"; 71 | this.caption.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 72 | // 73 | // AboutDialog 74 | // 75 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 76 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 77 | this.ClientSize = new System.Drawing.Size(552, 297); 78 | this.Controls.Add(this.caption); 79 | this.Controls.Add(this.title); 80 | this.Controls.Add(this.AboutRichTextBox); 81 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 82 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 83 | this.MaximizeBox = false; 84 | this.Name = "AboutDialog"; 85 | this.Text = "About"; 86 | this.ResumeLayout(false); 87 | 88 | } 89 | 90 | #endregion 91 | 92 | private System.Windows.Forms.RichTextBox AboutRichTextBox; 93 | private System.Windows.Forms.Label title; 94 | private System.Windows.Forms.Label caption; 95 | } 96 | } -------------------------------------------------------------------------------- /OpenRoC/AboutDialog.cs: -------------------------------------------------------------------------------- 1 | namespace oroc 2 | { 3 | using System.Diagnostics; 4 | using System.Windows.Forms; 5 | 6 | public partial class AboutDialog : Form 7 | { 8 | 9 | public AboutDialog() 10 | { 11 | InitializeComponent(); 12 | } 13 | 14 | private void OnAboutRichTextBoxLinkClicked(object sender, LinkClickedEventArgs e) 15 | { 16 | using (Process.Start(e.LinkText)) { /* no-op */ } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /OpenRoC/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /OpenRoC/Docs/main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HeliosInteractive/OpenRoC/9b69c54c28e230f795b48e92c2bff4ab29d80ad7/OpenRoC/Docs/main.png -------------------------------------------------------------------------------- /OpenRoC/Docs/process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HeliosInteractive/OpenRoC/9b69c54c28e230f795b48e92c2bff4ab29d80ad7/OpenRoC/Docs/process.png -------------------------------------------------------------------------------- /OpenRoC/Docs/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HeliosInteractive/OpenRoC/9b69c54c28e230f795b48e92c2bff4ab29d80ad7/OpenRoC/Docs/settings.png -------------------------------------------------------------------------------- /OpenRoC/Extensions.cs: -------------------------------------------------------------------------------- 1 | namespace oroc 2 | { 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Converters; 5 | 6 | using System; 7 | using System.IO; 8 | using System.Xml; 9 | using System.Drawing; 10 | using System.Xml.Linq; 11 | using System.Reflection; 12 | using System.Windows.Forms; 13 | using System.Xml.Serialization; 14 | 15 | internal static class Extensions 16 | { 17 | public static bool SetDoubleBuffered(this Control control, bool enable) 18 | { 19 | PropertyInfo doubleBufferPropertyInfo = control.GetType().GetProperty( 20 | "DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); 21 | 22 | if (doubleBufferPropertyInfo != null) 23 | { 24 | bool current = (bool)doubleBufferPropertyInfo.GetValue(control); 25 | 26 | if (current != enable) 27 | { 28 | doubleBufferPropertyInfo.SetValue(control, enable, null); 29 | return true; 30 | } 31 | } 32 | 33 | return false; 34 | } 35 | 36 | public static string ToXmlNodeString(this T self) 37 | { 38 | XmlSerializerNamespaces serializer_namespace = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty }); 39 | XmlWriterSettings serializer_settings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true }; 40 | XmlSerializer serializer = new XmlSerializer(typeof(T)); 41 | 42 | StringWriter string_writer = new StringWriter(); 43 | using (XmlWriter xml_writer = XmlWriter.Create(string_writer, serializer_settings)) 44 | { 45 | serializer.Serialize(xml_writer, self, serializer_namespace); 46 | return string_writer.ToString(); 47 | } 48 | } 49 | 50 | public static T FromXmlNodeString(string node, string root) 51 | { 52 | XmlReaderSettings serializer_settings = new XmlReaderSettings { ValidationType = ValidationType.None }; 53 | XmlSerializer serializer = new XmlSerializer(typeof(T), new XmlRootAttribute(root)); 54 | 55 | using (XmlReader xml_reader = XmlReader.Create(new StringReader(node), serializer_settings)) 56 | { 57 | return (T)serializer.Deserialize(xml_reader); 58 | } 59 | } 60 | 61 | public static XmlElement AsXmlElement(this XElement el) 62 | { 63 | var doc = new XmlDocument(); 64 | doc.Load(el.CreateReader()); 65 | return doc.DocumentElement; 66 | } 67 | 68 | public static void AppendText(this RichTextBox box, string text, Color color) 69 | { 70 | box.SelectionStart = box.TextLength; 71 | box.SelectionLength = 0; 72 | 73 | box.SelectionColor = color; 74 | box.AppendText(text); 75 | box.SelectionColor = box.ForeColor; 76 | } 77 | 78 | public static string ToJson(this object input) 79 | { 80 | var settings = new JsonSerializerSettings(); 81 | 82 | settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 83 | settings.Converters.Add(new StringEnumConverter()); 84 | 85 | return JsonConvert.SerializeObject(input, Newtonsoft.Json.Formatting.None, settings); 86 | } 87 | 88 | public static void SetupDataBind(this TextBox control, object instance, string prop) 89 | { 90 | control.SetupDataBind(nameof(control.Text), instance, prop); 91 | } 92 | 93 | public static void SetupDataBind(this CheckBox control, object instance, string prop) 94 | { 95 | control.SetupDataBind(nameof(control.Checked), instance, prop); 96 | } 97 | 98 | public static void SetupDataBind(this Control control, string dest, object instance, string src) 99 | { 100 | control.DataBindings.Add(new Binding(dest, instance, src)); 101 | } 102 | 103 | public static void ExecuteOnMainThread(this Form form, Action task) 104 | { 105 | form.Invoke((MethodInvoker)delegate 106 | { 107 | try { task?.Invoke(); } 108 | catch (Exception ex) { Log.e("Main thread execution failed: {0}", ex.Message); } 109 | }); 110 | } 111 | 112 | public static void ShiftLeft(this double[] array, double last_value = default(double)) 113 | { 114 | int last_index = array.Length - 1; 115 | Array.Copy(array, 1, array, 0, last_index); 116 | array[last_index] = last_value; 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /OpenRoC/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /OpenRoC/Logger.cs: -------------------------------------------------------------------------------- 1 | namespace oroc 2 | { 3 | using log4net; 4 | using log4net.Core; 5 | using log4net.Config; 6 | using log4net.Appender; 7 | 8 | using System; 9 | using System.IO; 10 | using System.Drawing; 11 | using System.Xml.Linq; 12 | using System.Windows.Forms; 13 | 14 | class Log 15 | { 16 | public static void d(string msg) { Logger.Instance.Debug(msg); } 17 | public static void d(string fmt, params object[] args) { Logger.Instance.DebugFormat(fmt, args); } 18 | public static void w(string msg) { Logger.Instance.Warn(msg); } 19 | public static void w(string fmt, params object[] args) { Logger.Instance.WarnFormat(fmt, args); } 20 | public static void e(string msg) { Logger.Instance.Error(msg); } 21 | public static void e(string fmt, params object[] args) { Logger.Instance.ErrorFormat(fmt, args); } 22 | public static void i(string msg) { Logger.Instance.Info(msg); } 23 | public static void i(string fmt, params object[] args) { Logger.Instance.InfoFormat(fmt, args); } 24 | } 25 | 26 | internal class Logger 27 | { 28 | public static readonly ILog Instance = LogManager.GetLogger(typeof(Logger)); 29 | 30 | public static void Configure(Form owner, RichTextBox logBox) 31 | { 32 | FileInfo config_file = new FileInfo( 33 | Path.Combine(Program.Directory, Properties.Resources.SettingsFileName)); 34 | 35 | if (!config_file.Exists) 36 | File.WriteAllText(config_file.FullName, Properties.Resources.SettingsBaseXml); 37 | 38 | XElement phoenix_root = null; 39 | 40 | try { phoenix_root = XElement.Load(config_file.FullName); } 41 | catch (Exception ex) 42 | { 43 | Log.e("Root element cannot be loaded: {0}", ex.Message); 44 | phoenix_root = XElement.Parse(Properties.Resources.SettingsBaseXml); 45 | } 46 | 47 | if (phoenix_root == null || phoenix_root.Name != Properties.Resources.SettingsRootNode) 48 | { 49 | Log.w("Phoenix node not found. It will be created."); 50 | phoenix_root = new XElement(Properties.Resources.SettingsRootNode); 51 | } 52 | 53 | XElement log4net_root = phoenix_root.Element(Properties.Resources.SettingsLog4NetNode); 54 | 55 | if (log4net_root == null) 56 | { 57 | Log.e("Options node not found. It will be created."); 58 | log4net_root = new XElement(Properties.Resources.SettingsLog4NetNode); 59 | phoenix_root.Add(log4net_root); 60 | } 61 | 62 | XmlConfigurator.Configure(log4net_root.AsXmlElement()); 63 | BasicConfigurator.Configure(new TextBoxAppender(logBox, owner)); 64 | 65 | Log.d("Logger configured."); 66 | } 67 | 68 | internal class TextBoxAppender : AppenderSkeleton 69 | { 70 | private RichTextBox textBox; 71 | 72 | public TextBoxAppender(RichTextBox box, Form box_owner) 73 | { 74 | textBox = box; 75 | Threshold = Level.All; 76 | box_owner.FormClosing += (s, e) => textBox = null; 77 | } 78 | 79 | protected override void Append(LoggingEvent loggingEvent) 80 | { 81 | if (textBox == null || textBox.Disposing || textBox.IsDisposed) 82 | return; 83 | 84 | textBox.BeginInvoke((MethodInvoker)delegate 85 | { 86 | textBox.AppendText(loggingEvent.RenderedMessage + Environment.NewLine, GetLevelColor(loggingEvent.Level)); 87 | 88 | if (!textBox.Visible) 89 | { 90 | textBox.SelectionStart = textBox.TextLength; 91 | textBox.ScrollToCaret(); 92 | } 93 | }); 94 | } 95 | 96 | static Color GetLevelColor(Level level) 97 | { 98 | if (level == Level.Error || level == Level.Critical || level == Level.Fatal) 99 | return Color.Red; 100 | else if (level == Level.Debug || level == Level.Notice) 101 | return Color.DimGray; 102 | else if (level == Level.Warn) 103 | return Color.Blue; 104 | else 105 | return Color.Black; 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /OpenRoC/LogsDialog.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace oroc 2 | { 3 | partial class LogsDialog 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(LogsDialog)); 32 | this.LogTextBox = new System.Windows.Forms.RichTextBox(); 33 | this.SuspendLayout(); 34 | // 35 | // LogTextBox 36 | // 37 | this.LogTextBox.Dock = System.Windows.Forms.DockStyle.Fill; 38 | this.LogTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 39 | this.LogTextBox.Location = new System.Drawing.Point(0, 0); 40 | this.LogTextBox.Name = "LogTextBox"; 41 | this.LogTextBox.ReadOnly = true; 42 | this.LogTextBox.Size = new System.Drawing.Size(499, 261); 43 | this.LogTextBox.TabIndex = 0; 44 | this.LogTextBox.Text = ""; 45 | this.LogTextBox.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.OnLogsDialogRichTextBoxLinkClicked); 46 | // 47 | // LogsDialog 48 | // 49 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 50 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 51 | this.ClientSize = new System.Drawing.Size(499, 261); 52 | this.Controls.Add(this.LogTextBox); 53 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 54 | this.Name = "LogsDialog"; 55 | this.Text = "Logs"; 56 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnLogsDialogFormClosing); 57 | this.ResumeLayout(false); 58 | 59 | } 60 | 61 | #endregion 62 | 63 | private System.Windows.Forms.RichTextBox LogTextBox; 64 | } 65 | } -------------------------------------------------------------------------------- /OpenRoC/LogsDialog.cs: -------------------------------------------------------------------------------- 1 | namespace oroc 2 | { 3 | using System; 4 | using System.Diagnostics; 5 | using System.Windows.Forms; 6 | 7 | public partial class LogsDialog : Form 8 | { 9 | public LogsDialog() 10 | { 11 | InitializeComponent(); 12 | 13 | if (LogTextBox.Handle != IntPtr.Zero) 14 | Logger.Configure(this, LogTextBox); 15 | } 16 | 17 | private void OnLogsDialogFormClosing(object sender, FormClosingEventArgs e) 18 | { 19 | if (e.CloseReason == CloseReason.UserClosing) 20 | { 21 | e.Cancel = true; 22 | Hide(); 23 | } 24 | } 25 | 26 | private void OnLogsDialogRichTextBoxLinkClicked(object sender, LinkClickedEventArgs e) 27 | { 28 | using (Process.Start(e.LinkText)) { /* no-op */ } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /OpenRoC/MainDialog.cs: -------------------------------------------------------------------------------- 1 | namespace oroc 2 | { 3 | using liboroc; 4 | 5 | using System; 6 | using System.IO; 7 | using System.Windows.Forms; 8 | using System.Collections.Generic; 9 | using System.Windows.Forms.DataVisualization.Charting; 10 | 11 | public partial class MainDialog : Form 12 | { 13 | private ExecutorService screenshotService; 14 | private Metrics.Manager metricsManager; 15 | private SensuInterface sensuInterface; 16 | private ProcessDialog editProcessForm; 17 | private ProcessDialog addProcessForm; 18 | private SettingsDialog settingsForm; 19 | private AboutDialog aboutForm; 20 | private LogsDialog logsForm; 21 | 22 | private Series CpuChart; 23 | private Series GpuChart; 24 | private Series RamChart; 25 | 26 | public ProcessManager ProcessManager { get; private set; } 27 | private bool inhibitAutoCheck = false; 28 | 29 | public MainDialog() 30 | { 31 | InitializeComponent(); 32 | logsForm = new LogsDialog(); 33 | SetupMainDialogStatusTexts(); 34 | HandleCreated += OnHandleCreated; 35 | ProcessManager = new ProcessManager(); 36 | metricsManager = new Metrics.Manager(); 37 | screenshotService = new ExecutorService(); 38 | 39 | ProcessListView.SetDoubleBuffered(true); 40 | MetricsChart.SetDoubleBuffered(true); 41 | } 42 | 43 | private void OnHandleCreated(object sender, EventArgs e) 44 | { 45 | Log.d("Main dialog handle created."); 46 | 47 | List launchOptions = Settings.Instance.Read> 48 | (Properties.Resources.SettingsProcessListNode); 49 | 50 | Log.d("Launch options parsed. Number of launch processes: {0}", launchOptions.Count); 51 | 52 | if (Settings.Instance.IsSensuInterfaceEnabled) 53 | { 54 | SensuInterfaceUpdateTimer.Enabled = true; 55 | SensuInterfaceUpdateTimer.Tick += OnSensuInterfaceUpdateTimerTick; 56 | SetSensuInterfaceUpdateTimerInterval(Settings.Instance.SensuInterfaceTTL); 57 | 58 | sensuInterface = new SensuInterface( 59 | ProcessManager, 60 | Settings.Instance.SensuInterfaceHost, 61 | Settings.Instance.SensuInterfacePort, 62 | Settings.Instance.SensuInterfaceTTL); 63 | } 64 | 65 | launchOptions.ForEach((opt) => { ProcessManager.Add(opt); }); 66 | ProcessManager.ProcessesChanged += OnProcessManagerPropertyChanged; 67 | 68 | CpuChart = MetricsChart.Series[nameof(CpuChart)]; 69 | GpuChart = MetricsChart.Series[nameof(GpuChart)]; 70 | RamChart = MetricsChart.Series[nameof(RamChart)]; 71 | } 72 | 73 | public void SetSensuInterfaceUpdateTimerInterval(uint seconds) 74 | { 75 | int interval = (int)TimeSpan 76 | .FromSeconds(seconds * 0.8) 77 | .TotalMilliseconds; 78 | 79 | if (SensuInterfaceUpdateTimer.Interval == interval) 80 | return; 81 | 82 | Log.i("Sensu checks TTL and timeout is: {0} seconds.", seconds); 83 | Log.i("Sensu checks interval is: {0} miliseconds.", interval); 84 | 85 | SensuInterfaceUpdateTimer.Interval = interval; 86 | sensuInterface?.SetTTL(seconds); 87 | } 88 | 89 | private void OnSensuInterfaceUpdateTimerTick(object sender, EventArgs e) 90 | { 91 | Log.d("Sending Sensu checks."); 92 | sensuInterface.SendChecks(); 93 | } 94 | 95 | private void OnProcessManagerPropertyChanged() 96 | { 97 | Settings.Instance.Write(Properties.Resources.SettingsProcessListNode, ProcessManager.Options); 98 | Settings.Instance.Save(); 99 | } 100 | 101 | private void OnProcessListViewResize(object sender, EventArgs e) 102 | { 103 | if (ProcessListView.Columns.Count > 0) 104 | ProcessListView.AutoResizeColumn( 105 | ProcessListView.Columns.Count - 1, 106 | ColumnHeaderAutoResizeStyle.HeaderSize); 107 | } 108 | 109 | public void UpdateProcessList() 110 | { 111 | foreach (ListViewItem item in ProcessListView.Items) 112 | if (!ProcessManager.Contains(item.Text)) 113 | item.Remove(); 114 | 115 | ProcessManager.Runners.ForEach(p => 116 | { 117 | if (ProcessListView.Items.ContainsKey(p.ProcessOptions.Path)) 118 | { 119 | ProcessListView.Items[p.ProcessOptions.Path].Checked = p.State != ProcessRunner.Status.Disabled; 120 | ProcessListView.Items[p.ProcessOptions.Path].SubItems[1].Text = p.GetStateString(); 121 | } 122 | else 123 | { 124 | ListViewItem item = new ListViewItem(); 125 | 126 | item.Checked = p.State != ProcessRunner.Status.Disabled; 127 | item.Text = p.ProcessOptions.Path; 128 | item.Name = p.ProcessOptions.Path; 129 | item.SubItems.Add(p.State.ToString()); 130 | 131 | p.StateChanged += () => { Log.i("Process {0} changed state to: {1}", p.ProcessOptions.Path, p.State); }; 132 | p.OptionsChanged += () => { Log.d("Process changed options to: {0}", p.ProcessOptions.ToJson()); }; 133 | p.ProcessCrashed += () => 134 | { 135 | Log.e("Process {0} crashed or stopped.", p.ProcessOptions.Path); 136 | 137 | if (p.ProcessOptions.ScreenShotEnabled) 138 | TakeScreenShot(); 139 | }; 140 | 141 | ProcessListView.Items.Add(item); 142 | } 143 | }); 144 | } 145 | 146 | private void OnSettingsButtonClick(object sender, EventArgs e) 147 | { 148 | HandleDialogRequest(ref settingsForm); 149 | } 150 | 151 | private void OnAddButtonClick(object sender, EventArgs e) 152 | { 153 | HandleDialogRequest(ref addProcessForm); 154 | } 155 | 156 | private void OnAboutButtonClick(object sender, EventArgs e) 157 | { 158 | HandleDialogRequest(ref aboutForm); 159 | } 160 | 161 | private void OnLogButtonClick(object sender, EventArgs e) 162 | { 163 | HandleDialogRequest(ref logsForm); 164 | } 165 | 166 | private void HandleDialogRequest(ref T host) where T : Form, new() 167 | { 168 | if (host == null || host.IsDisposed) 169 | { 170 | host = new T(); 171 | host.Owner = this; 172 | 173 | if (host.Handle == IntPtr.Zero) 174 | Log.d("Forced handle to be created."); 175 | } 176 | 177 | if (!host.Visible) 178 | { 179 | host.Show(); 180 | host.Focus(); 181 | } 182 | else 183 | { 184 | host.Focus(); 185 | return; 186 | } 187 | } 188 | 189 | private void OnProcessListViewItemChecked(object sender, ItemCheckedEventArgs e) 190 | { 191 | if (e.Item.Checked == (ProcessManager.Get(e.Item.Text).State != ProcessRunner.Status.Disabled)) 192 | return; 193 | 194 | if (e.Item.Checked) 195 | ProcessManager.Get(e.Item.Text).RestoreState(); 196 | else 197 | ProcessManager.Get(e.Item.Text).State = ProcessRunner.Status.Disabled; 198 | } 199 | 200 | private void OnMainDialogUpdateTimerTick(object sender, EventArgs e) 201 | { 202 | ProcessManager.Runners.ForEach(p => p.Monitor()); 203 | metricsManager.Update(); 204 | UpdateProcessList(); 205 | 206 | CpuChart?.Points.DataBindY(metricsManager.CpuSamples); 207 | GpuChart?.Points.DataBindY(metricsManager.GpuSamples); 208 | RamChart?.Points.DataBindY(metricsManager.RamSamples); 209 | } 210 | 211 | #region StatusBar text feature 212 | 213 | public void SetStatusBarText(Control control, string text) 214 | { 215 | control.MouseEnter += (s, e) => { StatusText.Text = text; }; 216 | control.MouseLeave += (s, e) => { ResetStatusBarText(); }; 217 | } 218 | 219 | public void SetStatusBarText(ToolStripItem control, string text) 220 | { 221 | control.MouseEnter += (s, e) => { StatusText.Text = text; }; 222 | control.MouseLeave += (s, e) => { ResetStatusBarText(); }; 223 | } 224 | 225 | public void ResetStatusBarText() 226 | { 227 | StatusText.Text = Properties.Resources.StatusTextDefaultString; 228 | } 229 | 230 | private void SetupMainDialogStatusTexts() 231 | { 232 | ResetStatusBarText(); 233 | SetStatusBarText(AddButton, "Add a new process to monitor."); 234 | SetStatusBarText(DeleteButton, "Delete selected processes."); 235 | SetStatusBarText(SettingsButton, "Adjust OpenRoC settings."); 236 | SetStatusBarText(LogsButton, "Open logging history window."); 237 | SetStatusBarText(AboutButton, "Read about OpenRoC project."); 238 | SetStatusBarText(ContextMenuAddButton, "Add a new process."); 239 | SetStatusBarText(ContextMenuEditButton, "Edit the process."); 240 | SetStatusBarText(ContextMenuDeleteButton, "Delete selected processes."); 241 | SetStatusBarText(ContextMenuDisableButton, "Disable selected processes."); 242 | SetStatusBarText(ContextMenuStart, "Run selected processes if they are stopped."); 243 | SetStatusBarText(ContextMenuStop, "Stop selected processes if they are running."); 244 | SetStatusBarText(ContextMenuShow, "Attempt to bring the main Window of the selected processes to top."); 245 | SetStatusBarText(MetricsChart, "Overall performance graph of this machine over past few seconds."); 246 | } 247 | 248 | #endregion 249 | 250 | #region Start minimized support 251 | 252 | protected override void SetVisibleCore(bool value) 253 | { 254 | if (!IsHandleCreated) 255 | { 256 | CreateHandle(); 257 | base.SetVisibleCore(!Settings.Instance.IsStartMinimizedEnabled); 258 | } 259 | else 260 | { 261 | base.SetVisibleCore(value); 262 | } 263 | } 264 | 265 | #endregion 266 | 267 | #region Taskbar right-click context menu event callbacks 268 | 269 | private void OnTaskbarContextMenuToggleViewButtonClick(object sender, EventArgs e) 270 | { 271 | if (e is MouseEventArgs && (e as MouseEventArgs).Button != MouseButtons.Left) 272 | return; 273 | 274 | Visible = !Visible; 275 | 276 | if (Visible) 277 | Focus(); 278 | } 279 | 280 | private void OnTaskbarContextMenuExitButtonClick(object sender, EventArgs e) 281 | { 282 | Close(); 283 | } 284 | 285 | #endregion 286 | 287 | #region Process right-click context menu event callbacks 288 | 289 | private void OnContextMenuEditButtonClick(object sender, EventArgs e) 290 | { 291 | if (ProcessListView.FocusedItem == null || ProcessListView.SelectedItems.Count == 0) 292 | { 293 | MessageBox.Show( 294 | "Please select a Process to edit.", 295 | "No Process selected", 296 | MessageBoxButtons.OK, 297 | MessageBoxIcon.Warning); 298 | 299 | return; 300 | } 301 | 302 | ProcessRunner process = ProcessManager.Get(ProcessListView.FocusedItem.Text); 303 | 304 | if (editProcessForm == null || editProcessForm.IsDisposed) 305 | { 306 | editProcessForm = new ProcessDialog(process.ProcessOptions); 307 | editProcessForm.Owner = this; 308 | } 309 | 310 | if (!editProcessForm.Visible) 311 | editProcessForm.Show(); 312 | else 313 | editProcessForm.Focus(); 314 | } 315 | 316 | private void OnContextMenuDeleteButtonClick(object sender, EventArgs e) 317 | { 318 | if (ProcessListView.SelectedItems.Count == 0) 319 | { 320 | MessageBox.Show( 321 | "Please select Processes to delete.", 322 | "No Processes selected", 323 | MessageBoxButtons.OK, 324 | MessageBoxIcon.Warning); 325 | 326 | return; 327 | } 328 | 329 | foreach (ListViewItem item in ProcessListView.SelectedItems) 330 | ProcessManager.Remove(item.Text); 331 | 332 | UpdateProcessList(); 333 | } 334 | 335 | private void OnContextMenuDisableButtonClick(object sender, EventArgs e) 336 | { 337 | if (ProcessListView.SelectedItems.Count == 0) 338 | { 339 | MessageBox.Show( 340 | "Please select Processes to disable.", 341 | "No Processes selected", 342 | MessageBoxButtons.OK, 343 | MessageBoxIcon.Warning); 344 | 345 | return; 346 | } 347 | 348 | foreach (ListViewItem item in ProcessListView.SelectedItems) 349 | ProcessManager.Get(item.Text).State = ProcessRunner.Status.Disabled; 350 | } 351 | 352 | private void OnContextMenuShowClick(object sender, EventArgs e) 353 | { 354 | if (ProcessListView.SelectedItems.Count == 0) 355 | { 356 | MessageBox.Show( 357 | "Please select Processes to show.", 358 | "No Processes selected", 359 | MessageBoxButtons.OK, 360 | MessageBoxIcon.Warning); 361 | 362 | return; 363 | } 364 | 365 | foreach (ListViewItem item in ProcessListView.SelectedItems) 366 | ProcessManager.Get(item.Text).BringToFront(); 367 | } 368 | 369 | private void OnContextMenuStopClick(object sender, EventArgs e) 370 | { 371 | if (ProcessListView.SelectedItems.Count == 0) 372 | { 373 | MessageBox.Show( 374 | "Please select Processes to stop.", 375 | "No Processes selected", 376 | MessageBoxButtons.OK, 377 | MessageBoxIcon.Warning); 378 | 379 | return; 380 | } 381 | 382 | foreach (ListViewItem item in ProcessListView.SelectedItems) 383 | ProcessManager.Get(item.Text).Stop(); 384 | } 385 | 386 | private void OnContextMenuStartClick(object sender, EventArgs e) 387 | { 388 | if (ProcessListView.SelectedItems.Count == 0) 389 | { 390 | MessageBox.Show( 391 | "Please select Processes to start.", 392 | "No Processes selected", 393 | MessageBoxButtons.OK, 394 | MessageBoxIcon.Warning); 395 | 396 | return; 397 | } 398 | 399 | foreach (ListViewItem item in ProcessListView.SelectedItems) 400 | ProcessManager.Get(item.Text).Start(); 401 | } 402 | 403 | #endregion 404 | 405 | #region Drag and drop file support 406 | 407 | private void OnProcessListViewDragDrop(object sender, DragEventArgs e) 408 | { 409 | string[] dragged_files = e.Data.GetData(DataFormats.FileDrop, false) as string[]; 410 | 411 | if (dragged_files == null) 412 | return; 413 | 414 | foreach (string dragged_file in dragged_files) 415 | { 416 | if (!ProcessManager.Contains(dragged_file)) 417 | { 418 | ProcessOptions opts = new ProcessOptions(); 419 | 420 | opts.Path = dragged_file; 421 | opts.WorkingDirectory = Path.GetDirectoryName(opts.Path); 422 | 423 | ProcessManager.Add(opts); 424 | } 425 | } 426 | 427 | UpdateProcessList(); 428 | } 429 | 430 | private void OnProcessListViewDragEnter(object sender, DragEventArgs e) 431 | { 432 | e.Effect = DragDropEffects.Copy; 433 | } 434 | 435 | #endregion 436 | 437 | #region Disable auto-check feature of ListView on double-click 438 | 439 | private void OnProcessListViewMouseUp(object sender, MouseEventArgs e) 440 | { 441 | inhibitAutoCheck = false; 442 | } 443 | 444 | private void OnProcessListViewMouseDown(object sender, MouseEventArgs e) 445 | { 446 | inhibitAutoCheck = true; 447 | } 448 | 449 | private void OnProcessListViewItemCheck(object sender, ItemCheckEventArgs e) 450 | { 451 | if (inhibitAutoCheck) 452 | e.NewValue = e.CurrentValue; 453 | } 454 | 455 | #endregion 456 | 457 | #region ScreenShot support 458 | 459 | public void TakeScreenShot() 460 | { 461 | if (!Directory.Exists(Program.ScreenShotDirectory)) 462 | Directory.CreateDirectory(Program.ScreenShotDirectory); 463 | 464 | Log.i("ScreenShot queued for execution."); 465 | 466 | screenshotService.Accept(() => 467 | { 468 | Log.i("ScreenShot is being taken..."); 469 | 470 | using (var picture = Pranas.ScreenshotCapture.TakeScreenshot()) 471 | { 472 | string name = Path.Combine( 473 | Program.ScreenShotDirectory, 474 | string.Format("{0}.png", DateTime.Now.ToFileTime())); 475 | 476 | picture.Save(name); 477 | 478 | Log.i("ScreenShot is saved to: {0}", name); 479 | } 480 | }); 481 | } 482 | 483 | #endregion 484 | 485 | private void DisposeAddedComponents() 486 | { 487 | screenshotService?.Dispose(); 488 | metricsManager?.Dispose(); 489 | ProcessManager?.Dispose(); 490 | sensuInterface?.Dispose(); 491 | editProcessForm?.Dispose(); 492 | addProcessForm?.Dispose(); 493 | settingsForm?.Dispose(); 494 | aboutForm?.Dispose(); 495 | logsForm?.Dispose(); 496 | 497 | screenshotService = null; 498 | metricsManager = null; 499 | ProcessManager = null; 500 | sensuInterface = null; 501 | editProcessForm = null; 502 | addProcessForm = null; 503 | settingsForm = null; 504 | aboutForm = null; 505 | logsForm = null; 506 | } 507 | } 508 | } 509 | -------------------------------------------------------------------------------- /OpenRoC/Metrics/Collector.cs: -------------------------------------------------------------------------------- 1 | namespace oroc.Metrics 2 | { 3 | using System; 4 | using System.Linq; 5 | using System.Collections.Generic; 6 | 7 | using OpenHardwareMonitor.Hardware; 8 | 9 | public abstract class ICollector 10 | { 11 | protected readonly IHardware Hardware; 12 | protected readonly List Sensors; 13 | public double CurrentSample { get; private set; } = 0.0d; 14 | 15 | protected ICollector(IHardware hardware) 16 | { 17 | Hardware = hardware; 18 | Sensors = new List(); 19 | 20 | if (Hardware != null) 21 | { 22 | Hardware.SensorAdded += (sensor) => 23 | { 24 | Log.i("Sensor {0} is added.", sensor.Name); 25 | 26 | if (Sensors != null) 27 | { 28 | if (sensor.SensorType == SensorType.Load) 29 | Sensors.Add(sensor); 30 | } 31 | }; 32 | 33 | Hardware.SensorRemoved += (sensor) => 34 | { 35 | Log.i("Sensor {0} is removed.", sensor.Name); 36 | 37 | if (Sensors != null) 38 | { 39 | if (sensor.SensorType == SensorType.Load) 40 | Sensors.Remove(sensor); 41 | } 42 | }; 43 | 44 | foreach (ISensor sensor in Hardware.Sensors) 45 | { 46 | if (sensor.SensorType == SensorType.Load) 47 | { 48 | Sensors.Add(sensor); 49 | } 50 | } 51 | } 52 | } 53 | 54 | public void Update() 55 | { 56 | if (Hardware == null || Sensors.Count == 0) 57 | return; 58 | 59 | Hardware.Update(); 60 | 61 | foreach (IHardware subhardware in Hardware.SubHardware) 62 | subhardware.Update(); 63 | 64 | try 65 | { 66 | CurrentSample = Sensors 67 | .Where(sensor => sensor.Value.HasValue && sensor.Value.Value > 0) 68 | .Average(sensor => sensor.Value.Value) 69 | / 100d; 70 | } 71 | catch (InvalidOperationException) { /* no samples this tick */ } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /OpenRoC/Metrics/CpuCollector.cs: -------------------------------------------------------------------------------- 1 | namespace oroc.Metrics 2 | { 3 | using OpenHardwareMonitor.Hardware; 4 | 5 | public class CpuCollector : ICollector 6 | { 7 | public CpuCollector(Computer computer) 8 | : base(GetFirstCpu(computer)) 9 | { /* no-op */ } 10 | 11 | private static IHardware GetFirstCpu(Computer computer) 12 | { 13 | IHardware defaultHardware = null; 14 | 15 | foreach (IHardware hardwareItem in computer.Hardware) 16 | { 17 | if (hardwareItem.HardwareType == HardwareType.CPU) 18 | { 19 | defaultHardware = hardwareItem; 20 | } 21 | } 22 | 23 | return defaultHardware; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /OpenRoC/Metrics/GpuCollector.cs: -------------------------------------------------------------------------------- 1 | namespace oroc.Metrics 2 | { 3 | using OpenHardwareMonitor.Hardware; 4 | 5 | public class GpuCollector : ICollector 6 | { 7 | public GpuCollector(Computer computer) 8 | : base(GetFirstGpu(computer)) 9 | { /* no-op */ } 10 | 11 | private static IHardware GetFirstGpu(Computer computer) 12 | { 13 | IHardware defaultHardware = null; 14 | 15 | foreach (IHardware hardwareItem in computer.Hardware) 16 | { 17 | if (hardwareItem.HardwareType == HardwareType.GpuAti || 18 | hardwareItem.HardwareType == HardwareType.GpuNvidia) 19 | { 20 | defaultHardware = hardwareItem; 21 | } 22 | } 23 | 24 | return defaultHardware; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /OpenRoC/Metrics/Manager.cs: -------------------------------------------------------------------------------- 1 | namespace oroc.Metrics 2 | { 3 | using liboroc; 4 | 5 | using System; 6 | using System.Linq; 7 | 8 | using OpenHardwareMonitor.Hardware; 9 | 10 | public class Manager : IDisposable 11 | { 12 | private Computer computer; 13 | private ICollector cpuCollector; 14 | private ICollector gpuCollector; 15 | private ICollector ramCollector; 16 | private ExecutorService setupService; 17 | private volatile bool setupFinished; 18 | 19 | public double[] CpuSamples { get; private set; } 20 | 21 | public double[] GpuSamples { get; private set; } 22 | 23 | public double[] RamSamples { get; private set; } 24 | 25 | public Manager() 26 | { 27 | setupService = new ExecutorService(); 28 | setupFinished = false; 29 | 30 | var initial_sensor_value = 0.0d; 31 | var initial_sensor_count = 50; 32 | 33 | CpuSamples = new double[initial_sensor_count]; 34 | CpuSamples = Enumerable.Repeat(initial_sensor_value, initial_sensor_count).ToArray(); 35 | 36 | GpuSamples = new double[initial_sensor_count]; 37 | GpuSamples = Enumerable.Repeat(initial_sensor_value, initial_sensor_count).ToArray(); 38 | 39 | RamSamples = new double[initial_sensor_count]; 40 | RamSamples = Enumerable.Repeat(initial_sensor_value, initial_sensor_count).ToArray(); 41 | 42 | setupService.Accept(() => 43 | { 44 | computer = new Computer 45 | { 46 | CPUEnabled = true, 47 | GPUEnabled = true, 48 | RAMEnabled = true, 49 | }; 50 | 51 | computer.Open(); 52 | 53 | cpuCollector = new CpuCollector(computer); 54 | gpuCollector = new GpuCollector(computer); 55 | ramCollector = new RamCollector(computer); 56 | 57 | setupFinished = true; 58 | }); 59 | } 60 | 61 | public void Update() 62 | { 63 | if (!setupFinished) 64 | return; 65 | 66 | cpuCollector.Update(); 67 | gpuCollector.Update(); 68 | ramCollector.Update(); 69 | 70 | CpuSamples.ShiftLeft(cpuCollector.CurrentSample); 71 | GpuSamples.ShiftLeft(gpuCollector.CurrentSample); 72 | RamSamples.ShiftLeft(ramCollector.CurrentSample); 73 | } 74 | 75 | #region IDisposable Support 76 | public bool IsDisposed { get; private set; } = false; 77 | 78 | protected virtual void Dispose(bool disposing) 79 | { 80 | if (!IsDisposed) 81 | { 82 | IsDisposed = true; 83 | 84 | if (disposing) 85 | { 86 | setupService?.Dispose(); 87 | computer?.Close(); 88 | } 89 | 90 | setupService = null; 91 | computer = null; 92 | } 93 | } 94 | 95 | public void Dispose() 96 | { 97 | Dispose(true); 98 | } 99 | #endregion 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /OpenRoC/Metrics/RamCollector.cs: -------------------------------------------------------------------------------- 1 | namespace oroc.Metrics 2 | { 3 | using OpenHardwareMonitor.Hardware; 4 | 5 | public class RamCollector : ICollector 6 | { 7 | public RamCollector(Computer computer) 8 | : base(GetFirstRam(computer)) 9 | { /* no-op */ } 10 | 11 | private static IHardware GetFirstRam(Computer computer) 12 | { 13 | IHardware defaultHardware = null; 14 | 15 | foreach (IHardware hardwareItem in computer.Hardware) 16 | { 17 | if (hardwareItem.HardwareType == HardwareType.RAM) 18 | { 19 | defaultHardware = hardwareItem; 20 | } 21 | } 22 | 23 | return defaultHardware; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /OpenRoC/OpenRoC.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {374DFCEE-DEEA-4D48-958E-0C8F64E9FCF6} 8 | WinExe 9 | Properties 10 | oroc 11 | OpenRoC 12 | v4.5.2 13 | 512 14 | true 15 | 16 | 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | true 28 | false 29 | 30 | 31 | AnyCPU 32 | pdbonly 33 | true 34 | bin\Release\ 35 | TRACE 36 | prompt 37 | 4 38 | false 39 | true 40 | 41 | 42 | oroc.Program 43 | 44 | 45 | phoenix.ico 46 | 47 | 48 | 49 | 50 | packages\log4net.2.0.5\lib\net45-full\log4net.dll 51 | True 52 | 53 | 54 | packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 55 | True 56 | 57 | 58 | packages\OpenHardwareMonitor.0.7.1\lib\net40\OpenHardwareMonitorLib.dll 59 | True 60 | 61 | 62 | packages\Pranas.ScreenshotCapture.1.0.11\lib\net40\Pranas.ScreenshotCapture.dll 63 | True 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | Form 77 | 78 | 79 | AboutDialog.cs 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | Form 90 | 91 | 92 | ProcessDialog.cs 93 | 94 | 95 | Form 96 | 97 | 98 | LogsDialog.cs 99 | 100 | 101 | Form 102 | 103 | 104 | MainDialog.cs 105 | 106 | 107 | 108 | 109 | 110 | 111 | Form 112 | 113 | 114 | SettingsDialog.cs 115 | 116 | 117 | AboutDialog.cs 118 | 119 | 120 | ProcessDialog.cs 121 | 122 | 123 | LogsDialog.cs 124 | 125 | 126 | MainDialog.cs 127 | 128 | 129 | ResXFileCodeGenerator 130 | Resources.Designer.cs 131 | Designer 132 | 133 | 134 | True 135 | Resources.resx 136 | True 137 | 138 | 139 | SettingsDialog.cs 140 | 141 | 142 | 143 | SettingsSingleFileGenerator 144 | Settings.Designer.cs 145 | 146 | 147 | True 148 | Settings.settings 149 | True 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | {90c91845-e5ae-42d2-8cad-e52564c344d0} 163 | libOpenRoC 164 | 165 | 166 | 167 | 168 | 169 | 170 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 171 | 172 | 173 | 174 | 181 | -------------------------------------------------------------------------------- /OpenRoC/OpenRoC.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRoC", "OpenRoC.csproj", "{374DFCEE-DEEA-4D48-958E-0C8F64E9FCF6}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "libOpenRoC", "..\libOpenRoC\libOpenRoC.csproj", "{90C91845-E5AE-42D2-8CAD-E52564C344D0}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testOpenRoC", "..\testOpenRoC\testOpenRoC.csproj", "{67901A36-B033-42D1-9651-02E1535FD389}" 11 | ProjectSection(ProjectDependencies) = postProject 12 | {AB679701-4781-4AE5-A484-7FDBAB6C0E48} = {AB679701-4781-4AE5-A484-7FDBAB6C0E48} 13 | EndProjectSection 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "testProcessWindowed", "testProcessWindowed\testProcessWindowed.csproj", "{AB679701-4781-4AE5-A484-7FDBAB6C0E48}" 16 | EndProject 17 | Global 18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 19 | Debug|Any CPU = Debug|Any CPU 20 | Release|Any CPU = Release|Any CPU 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {374DFCEE-DEEA-4D48-958E-0C8F64E9FCF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 24 | {374DFCEE-DEEA-4D48-958E-0C8F64E9FCF6}.Debug|Any CPU.Build.0 = Debug|Any CPU 25 | {374DFCEE-DEEA-4D48-958E-0C8F64E9FCF6}.Release|Any CPU.ActiveCfg = Release|Any CPU 26 | {374DFCEE-DEEA-4D48-958E-0C8F64E9FCF6}.Release|Any CPU.Build.0 = Release|Any CPU 27 | {90C91845-E5AE-42D2-8CAD-E52564C344D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 28 | {90C91845-E5AE-42D2-8CAD-E52564C344D0}.Debug|Any CPU.Build.0 = Debug|Any CPU 29 | {90C91845-E5AE-42D2-8CAD-E52564C344D0}.Release|Any CPU.ActiveCfg = Release|Any CPU 30 | {90C91845-E5AE-42D2-8CAD-E52564C344D0}.Release|Any CPU.Build.0 = Release|Any CPU 31 | {67901A36-B033-42D1-9651-02E1535FD389}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 32 | {67901A36-B033-42D1-9651-02E1535FD389}.Debug|Any CPU.Build.0 = Debug|Any CPU 33 | {67901A36-B033-42D1-9651-02E1535FD389}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {67901A36-B033-42D1-9651-02E1535FD389}.Release|Any CPU.Build.0 = Release|Any CPU 35 | {AB679701-4781-4AE5-A484-7FDBAB6C0E48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 36 | {AB679701-4781-4AE5-A484-7FDBAB6C0E48}.Debug|Any CPU.Build.0 = Debug|Any CPU 37 | {AB679701-4781-4AE5-A484-7FDBAB6C0E48}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {AB679701-4781-4AE5-A484-7FDBAB6C0E48}.Release|Any CPU.Build.0 = Release|Any CPU 39 | EndGlobalSection 40 | GlobalSection(SolutionProperties) = preSolution 41 | HideSolutionNode = FALSE 42 | EndGlobalSection 43 | EndGlobal 44 | -------------------------------------------------------------------------------- /OpenRoC/ProcessDialog.cs: -------------------------------------------------------------------------------- 1 | namespace oroc 2 | { 3 | using liboroc; 4 | 5 | using System; 6 | using System.IO; 7 | using System.Diagnostics; 8 | using System.Windows.Forms; 9 | 10 | public partial class ProcessDialog : Form 11 | { 12 | public ProcessOptions Options; 13 | private OpenFileDialog filePicker; 14 | private FolderBrowserDialog folderPicker; 15 | 16 | public ProcessDialog() 17 | : this(new ProcessOptions()) 18 | { /* no-op */ } 19 | 20 | public ProcessDialog(ProcessOptions opts) 21 | { 22 | InitializeComponent(); 23 | 24 | Options = opts; 25 | filePicker = new OpenFileDialog(); 26 | folderPicker = new FolderBrowserDialog(); 27 | 28 | HandleCreated += OnProcessDialogHandleCreated; 29 | } 30 | 31 | private void OnProcessDialogHandleCreated(object sender, EventArgs e) 32 | { 33 | if (!(Owner is MainDialog)) 34 | { 35 | Log.e("Owner of Process Window is not the right type."); 36 | return; 37 | } 38 | 39 | MainDialog main_dialog = Owner as MainDialog; 40 | 41 | main_dialog.SetStatusBarText(ProcessOptionPathControl, "Path to process executable. Only executables (*.exe) are valid."); 42 | main_dialog.SetStatusBarText(ProcessOptionWorkingDirectoryControl, "Working directory of the chosen process executable"); 43 | 44 | main_dialog.SetStatusBarText(ProcessOptionCrashedIfNotRunningControl, "Assume process is crashed if it's not running (no effect when monitoring is disabled)."); 45 | main_dialog.SetStatusBarText(ProcessOptionCrashedIfUnresponsiveControl, "Assume crash if main Window is unresponsive (no effect when monitoring is disabled)."); 46 | main_dialog.SetStatusBarText(ProcessOptionDoubleCheckEnabledControl, "Enable crash double check."); 47 | main_dialog.SetStatusBarText(ProcessOptionDoubleCheckDurationControl, "Crash double check duration. After a crash, double check before killing the process"); 48 | main_dialog.SetStatusBarText(ProcessOptionGracePeriodEnabledControl, "Enable a grace period between relaunches of the process."); 49 | main_dialog.SetStatusBarText(ProcessOptionGracePeriodDurationControl, "Grace period duration. After a crash, a restart happens when grace period ends."); 50 | 51 | main_dialog.SetStatusBarText(ProcessOptionPreLaunchScriptEnabledControl, "Enable before launch script execution."); 52 | main_dialog.SetStatusBarText(ProcessOptionPreLaunchScriptPathControl, "Execute and wait for this script before starting the process."); 53 | 54 | main_dialog.SetStatusBarText(ProcessOptionAggressiveCleanupEnabledControl, "Enable aggressive cleanup after process crashes."); 55 | main_dialog.SetStatusBarText(ProcessOptionPostCrashScriptEnabledControl, "Enable after crash script execution."); 56 | main_dialog.SetStatusBarText(ProcessOptionPostCrashScriptPathControl, "Execute and wait for this script after process crashed."); 57 | 58 | main_dialog.SetStatusBarText(ProcessOptionScreenshotEnabledControl, "Take a screen-shot of the main display when process crashes."); 59 | main_dialog.SetStatusBarText(ProcessOptionAlwaysOnTopEnabledControl, "Keep main Window on-top (aggressive, conflicts with other always-on-top Windows)."); 60 | main_dialog.SetStatusBarText(ProcessOptionCommandLineEnabledControl, "Enable passing command line to the process."); 61 | main_dialog.SetStatusBarText(ProcessOptionCommandLineControl, "Command line to pass to the process executable."); 62 | main_dialog.SetStatusBarText(ProcessOptionEnvironmentVariablesEnabledControl, "Enable merging environment variables."); 63 | main_dialog.SetStatusBarText(ProcessOptionEnvironmentVariablesControl, "Environment variable list. Format: var1=val1;var2=val2;..."); 64 | 65 | main_dialog.SetStatusBarText(StartupStateStoppedControl, "Stop the process when it is added to the process list for the first time."); 66 | main_dialog.SetStatusBarText(StartupStateRunningControl, "Run the process when it is added to the process list for the first time."); 67 | main_dialog.SetStatusBarText(StartupStateDisabledControl, "Do not monitor the process when it is added to the process list for the first time."); 68 | 69 | SetupDataBindings(); 70 | SyncCheckedStates(); 71 | } 72 | 73 | private void SetupDataBindings() 74 | { 75 | ProcessOptionPathControl.SetupDataBind(Options, nameof(Options.Path)); 76 | ProcessOptionWorkingDirectoryControl.SetupDataBind(Options, nameof(Options.WorkingDirectory)); 77 | 78 | ProcessOptionCrashedIfNotRunningControl.SetupDataBind(Options, nameof(Options.CrashedIfNotRunning)); 79 | ProcessOptionCrashedIfUnresponsiveControl.SetupDataBind(Options, nameof(Options.CrashedIfUnresponsive)); 80 | ProcessOptionDoubleCheckEnabledControl.SetupDataBind(Options, nameof(Options.DoubleCheckEnabled)); 81 | ProcessOptionDoubleCheckDurationControl.SetupDataBind(Options, nameof(Options.DoubleCheckDuration)); 82 | ProcessOptionGracePeriodEnabledControl.SetupDataBind(Options, nameof(Options.GracePeriodEnabled)); 83 | ProcessOptionGracePeriodDurationControl.SetupDataBind(Options, nameof(Options.GracePeriodDuration)); 84 | 85 | ProcessOptionPreLaunchScriptEnabledControl.SetupDataBind(Options, nameof(Options.PreLaunchScriptEnabled)); 86 | ProcessOptionPreLaunchScriptPathControl.SetupDataBind(Options, nameof(Options.PreLaunchScriptPath)); 87 | 88 | ProcessOptionAggressiveCleanupEnabledControl.SetupDataBind(Options, nameof(Options.AggressiveCleanupEnabled)); 89 | ProcessOptionPostCrashScriptEnabledControl.SetupDataBind(Options, nameof(Options.PostCrashScriptEnabled)); 90 | ProcessOptionPostCrashScriptPathControl.SetupDataBind(Options, nameof(Options.PostCrashScriptPath)); 91 | 92 | ProcessOptionScreenshotEnabledControl.SetupDataBind(Options, nameof(Options.ScreenShotEnabled)); 93 | ProcessOptionAlwaysOnTopEnabledControl.SetupDataBind(Options, nameof(Options.AlwaysOnTopEnabled)); 94 | ProcessOptionCommandLineEnabledControl.SetupDataBind(Options, nameof(Options.CommandLineEnabled)); 95 | ProcessOptionCommandLineControl.SetupDataBind(Options, nameof(Options.CommandLine)); 96 | ProcessOptionEnvironmentVariablesEnabledControl.SetupDataBind(Options, nameof(Options.EnvironmentVariablesEnabled)); 97 | ProcessOptionEnvironmentVariablesControl.SetupDataBind(Options, nameof(Options.EnvironmentVariables)); 98 | } 99 | 100 | private void OnProcessOptionsSaveButtonClick(object sender, EventArgs e) 101 | { 102 | MainDialog main = Owner as MainDialog; 103 | 104 | if (main != null) 105 | { 106 | if (main.ProcessManager.Contains(Options.Path)) 107 | main.ProcessManager.Get(Options.Path).ProcessOptions = Options; 108 | else 109 | main.ProcessManager.Add(Options); 110 | 111 | main.UpdateProcessList(); 112 | } 113 | 114 | Close(); 115 | } 116 | 117 | private void OnProcessOptionsCancelButtonClick(object sender, EventArgs e) 118 | { 119 | Close(); 120 | } 121 | 122 | private void OnStartupStateRadioGroupCheckedChanged(object sender, EventArgs e) 123 | { 124 | if (StartupStateStoppedControl.Checked) 125 | Options.InitialStateEnumValue = ProcessRunner.Status.Stopped; 126 | else if (StartupStateRunningControl.Checked) 127 | Options.InitialStateEnumValue = ProcessRunner.Status.Running; 128 | else if (StartupStateDisabledControl.Checked) 129 | Options.InitialStateEnumValue = ProcessRunner.Status.Disabled; 130 | } 131 | 132 | private void SyncCheckedStates() 133 | { 134 | if (Options.InitialStateEnumValue == ProcessRunner.Status.Stopped) 135 | StartupStateStoppedControl.Checked = true; 136 | else if (Options.InitialStateEnumValue == ProcessRunner.Status.Running) 137 | StartupStateRunningControl.Checked = true; 138 | else if (Options.InitialStateEnumValue == ProcessRunner.Status.Disabled) 139 | StartupStateDisabledControl.Checked = true; 140 | 141 | OnStartupStateRadioGroupCheckedChanged(this, null); 142 | OnProcessOptionDoubleCheckEnabledControlCheckedChanged(this, null); 143 | OnProcessOptionGracePeriodEnabledControlCheckedChanged(this, null); 144 | OnProcessOptionPreLaunchScriptEnabledControlCheckedChanged(this, null); 145 | OnProcessOptionPostCrashScriptEnabledControlCheckedChanged(this, null); 146 | OnProcessOptionCommandLineEnabledControlCheckedChanged(this, null); 147 | OnProcessOptionEnvironmentVariablesEnabledControlCheckedChanged(this, null); 148 | } 149 | 150 | private void OnProcessOptionDoubleCheckEnabledControlCheckedChanged(object sender, EventArgs e) 151 | { 152 | CheckBox checkbox = ProcessOptionDoubleCheckEnabledControl; 153 | 154 | if (ProcessOptionDoubleCheckDurationControl.Enabled != checkbox.Checked) 155 | ProcessOptionDoubleCheckDurationControl.Enabled = checkbox.Checked; 156 | } 157 | 158 | private void OnProcessOptionGracePeriodEnabledControlCheckedChanged(object sender, EventArgs e) 159 | { 160 | CheckBox checkbox = ProcessOptionGracePeriodEnabledControl; 161 | 162 | if (ProcessOptionGracePeriodDurationControl.Enabled != checkbox.Checked) 163 | ProcessOptionGracePeriodDurationControl.Enabled = checkbox.Checked; 164 | } 165 | 166 | private void OnProcessOptionPreLaunchScriptEnabledControlCheckedChanged(object sender, EventArgs e) 167 | { 168 | CheckBox checkbox = ProcessOptionPreLaunchScriptEnabledControl; 169 | 170 | if (ProcessOptionPreLaunchScriptPathControl.Enabled != checkbox.Checked) 171 | ProcessOptionPreLaunchScriptPathControl.Enabled = checkbox.Checked; 172 | 173 | if (ProcessOptionPreLaunchScriptButton.Enabled != checkbox.Checked) 174 | ProcessOptionPreLaunchScriptButton.Enabled = checkbox.Checked; 175 | } 176 | 177 | private void OnProcessOptionPostCrashScriptEnabledControlCheckedChanged(object sender, EventArgs e) 178 | { 179 | CheckBox checkbox = ProcessOptionPostCrashScriptEnabledControl; 180 | 181 | if (ProcessOptionPostCrashScriptPathControl.Enabled != checkbox.Checked) 182 | ProcessOptionPostCrashScriptPathControl.Enabled = checkbox.Checked; 183 | 184 | if (ProcessOptionPostCrashScriptButton.Enabled != checkbox.Checked) 185 | ProcessOptionPostCrashScriptButton.Enabled = checkbox.Checked; 186 | } 187 | 188 | private void OnProcessOptionCommandLineEnabledControlCheckedChanged(object sender, EventArgs e) 189 | { 190 | CheckBox checkbox = ProcessOptionCommandLineEnabledControl; 191 | 192 | if (ProcessOptionCommandLineControl.Enabled != checkbox.Checked) 193 | ProcessOptionCommandLineControl.Enabled = checkbox.Checked; 194 | } 195 | 196 | private void OnProcessOptionEnvironmentVariablesEnabledControlCheckedChanged(object sender, EventArgs e) 197 | { 198 | CheckBox checkbox = ProcessOptionEnvironmentVariablesEnabledControl; 199 | 200 | if (ProcessOptionEnvironmentVariablesControl.Enabled != checkbox.Checked) 201 | ProcessOptionEnvironmentVariablesControl.Enabled = checkbox.Checked; 202 | } 203 | 204 | private void OnSelectWorkingDirectoryClick(object sender, EventArgs e) 205 | { 206 | folderPicker.Description = "Please select a folder to continue"; 207 | 208 | if (folderPicker.ShowDialog() == DialogResult.OK) 209 | { 210 | Options.WorkingDirectory = folderPicker.SelectedPath; 211 | } 212 | } 213 | 214 | private void OnFileDialogRequested(object sender, EventArgs e) 215 | { 216 | if (ReferenceEquals(sender, SelectExecutablePath)) 217 | { 218 | filePicker.Filter = "Windows Executable (*.exe)|*.exe"; 219 | filePicker.Title = "Please select an executable to continue"; 220 | 221 | if (filePicker.ShowDialog() == DialogResult.OK) 222 | { 223 | Options.Path = filePicker.FileName; 224 | Options.WorkingDirectory = Path.GetDirectoryName(Options.Path); 225 | } 226 | } 227 | else if (ReferenceEquals(sender, ProcessOptionPreLaunchScriptButton)) 228 | { 229 | filePicker.Filter = "Shell Executable File (*.*)|*.*"; 230 | filePicker.Title = "Please select a script to continue"; 231 | 232 | if (filePicker.ShowDialog() == DialogResult.OK) 233 | { 234 | Options.PreLaunchScriptPath = filePicker.FileName; 235 | } 236 | } 237 | else if (ReferenceEquals(sender, ProcessOptionPostCrashScriptButton)) 238 | { 239 | filePicker.Filter = "Shell Executable File (*.*)|*.*"; 240 | filePicker.Title = "Please select a script to continue"; 241 | 242 | if (filePicker.ShowDialog() == DialogResult.OK) 243 | { 244 | Options.PostCrashScriptPath = filePicker.FileName; 245 | } 246 | } 247 | } 248 | 249 | private void OnOpenScreenshotDirectoryButtonClick(object sender, EventArgs e) 250 | { 251 | if (!Directory.Exists(Program.ScreenShotDirectory)) 252 | Directory.CreateDirectory(Program.ScreenShotDirectory); 253 | 254 | using (Process.Start(Program.ScreenShotDirectory)) { /* no-op */ } 255 | } 256 | 257 | private void DisposeAddedComponents() 258 | { 259 | folderPicker?.Dispose(); 260 | filePicker?.Dispose(); 261 | 262 | folderPicker = null; 263 | filePicker = null; 264 | } 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /OpenRoC/Program.cs: -------------------------------------------------------------------------------- 1 | namespace oroc 2 | { 3 | using System; 4 | using System.IO; 5 | using System.Threading; 6 | using System.Reflection; 7 | using System.Windows.Forms; 8 | 9 | static class Program 10 | { 11 | [STAThread] 12 | static int Main() 13 | { 14 | if (Settings.Instance.IsSingleInsntaceEnabled) 15 | { 16 | bool only_instance; 17 | using (Mutex applock = new Mutex(true, Properties.Resources.OpenRoCMutexName, out only_instance)) 18 | { 19 | if (!only_instance) 20 | { 21 | MessageBox.Show( 22 | "Another OpenRoC instance is already open.", 23 | "Multiple instances detected!", 24 | MessageBoxButtons.OK, 25 | MessageBoxIcon.Error); 26 | 27 | return 1; 28 | } 29 | else 30 | { 31 | Launch(); 32 | } 33 | } 34 | } 35 | else 36 | { 37 | Launch(); 38 | } 39 | 40 | Settings.Instance.Save(); 41 | return 0; 42 | } 43 | 44 | private static void Launch() 45 | { 46 | Application.EnableVisualStyles(); 47 | Application.SetCompatibleTextRenderingDefault(false); 48 | Application.Run(new MainDialog()); 49 | } 50 | 51 | public static string Directory 52 | { 53 | get { return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); } 54 | } 55 | 56 | public static string ScreenShotDirectory 57 | { 58 | get { return Path.Combine(Directory, ".ScreenShots"); } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /OpenRoC/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("OpenRoC")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("OpenRoC")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("374dfcee-deea-4d48-958e-0c8f64e9fcf6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /OpenRoC/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace oroc.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("oroc.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to oroclock. 65 | /// 66 | internal static string OpenRoCMutexName { 67 | get { 68 | return ResourceManager.GetString("OpenRoCMutexName", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). 74 | /// 75 | internal static System.Drawing.Icon phoenix { 76 | get { 77 | object obj = ResourceManager.GetObject("phoenix", resourceCulture); 78 | return ((System.Drawing.Icon)(obj)); 79 | } 80 | } 81 | 82 | /// 83 | /// Looks up a localized string similar to Application. 84 | /// 85 | internal static string SettingsApplicationNode { 86 | get { 87 | return ResourceManager.GetString("SettingsApplicationNode", resourceCulture); 88 | } 89 | } 90 | 91 | /// 92 | /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> 93 | ///<openroc> 94 | /// <log4net> 95 | /// <appender name="OpenRocRollingFile" type="log4net.Appender.RollingFileAppender"> 96 | /// <file value="OpenRoc.log" /> 97 | /// <appendToFile value="true" /> 98 | /// <maximumFileSize value="10MB" /> 99 | /// <maxSizeRollBackups value="20" /> 100 | /// <layout type="log4net.Layout.PatternLayout"> 101 | /// <conversionPattern value="[%5level] [%date{yyyy-MM-dd HH:mm:ss}] [%2thread] - %message%newline" /> 102 | /// [rest of string was truncated]";. 103 | /// 104 | internal static string SettingsBaseXml { 105 | get { 106 | return ResourceManager.GetString("SettingsBaseXml", resourceCulture); 107 | } 108 | } 109 | 110 | /// 111 | /// Looks up a localized string similar to OpenRoc.xml. 112 | /// 113 | internal static string SettingsFileName { 114 | get { 115 | return ResourceManager.GetString("SettingsFileName", resourceCulture); 116 | } 117 | } 118 | 119 | /// 120 | /// Looks up a localized string similar to log4net. 121 | /// 122 | internal static string SettingsLog4NetNode { 123 | get { 124 | return ResourceManager.GetString("SettingsLog4NetNode", resourceCulture); 125 | } 126 | } 127 | 128 | /// 129 | /// Looks up a localized string similar to options. 130 | /// 131 | internal static string SettingsOptionNode { 132 | get { 133 | return ResourceManager.GetString("SettingsOptionNode", resourceCulture); 134 | } 135 | } 136 | 137 | /// 138 | /// Looks up a localized string similar to Processes. 139 | /// 140 | internal static string SettingsProcessListNode { 141 | get { 142 | return ResourceManager.GetString("SettingsProcessListNode", resourceCulture); 143 | } 144 | } 145 | 146 | /// 147 | /// Looks up a localized string similar to openroc. 148 | /// 149 | internal static string SettingsRootNode { 150 | get { 151 | return ResourceManager.GetString("SettingsRootNode", resourceCulture); 152 | } 153 | } 154 | 155 | /// 156 | /// Looks up a localized string similar to Ready (drag and drop executables or click Add. Double click to Edit). 157 | /// 158 | internal static string StatusTextDefaultString { 159 | get { 160 | return ResourceManager.GetString("StatusTextDefaultString", resourceCulture); 161 | } 162 | } 163 | 164 | /// 165 | /// Looks up a localized string similar to ( 166 | /// _ ) ) 167 | /// _,(_)._ (( 168 | /// ___,(_______). ) 169 | /// ,'__. / \ /\_ 170 | /// /,' / |""| \ / / 171 | ///| | | |__| |,' / 172 | /// \`.| / 173 | /// `. : : / 174 | /// `. :.,' 175 | /// `-.________,-'. 176 | /// 177 | internal static string Teapot { 178 | get { 179 | return ResourceManager.GetString("Teapot", resourceCulture); 180 | } 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /OpenRoC/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | oroclock 122 | 123 | 124 | 125 | ..\phoenix.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | Application 129 | 130 | 131 | ..\Resources\openroc.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 132 | 133 | 134 | OpenRoc.xml 135 | 136 | 137 | log4net 138 | 139 | 140 | options 141 | 142 | 143 | Processes 144 | 145 | 146 | openroc 147 | 148 | 149 | Ready (drag and drop executables or click Add. Double click to Edit) 150 | 151 | 152 | ( 153 | _ ) ) 154 | _,(_)._ (( 155 | ___,(_______). ) 156 | ,'__. / \ /\_ 157 | /,' / |""| \ / / 158 | | | | |__| |,' / 159 | \`.| / 160 | `. : : / 161 | `. :.,' 162 | `-.________,-' 163 | Teapot, duh. 164 | 165 | -------------------------------------------------------------------------------- /OpenRoC/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace oroc.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /OpenRoC/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /OpenRoC/Resources/OpenRoc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |