├── .gitignore ├── App.config ├── ColorFile.cs ├── LICENSE ├── LogView.cs ├── LogView.resx ├── MonitorController.cs ├── MonitorView.Designer.cs ├── MonitorView.cs ├── MonitorView.resx ├── PathUtil.cs ├── ProcessModel.cs ├── Program.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── TabSettings.Designer.cs └── TabSettings.settings ├── README.md ├── SearchDialog.Designer.cs ├── SearchDialog.cs ├── SearchDialog.resx ├── ServiceMonitor.csproj ├── ServiceMonitor.sln ├── TabSettings.cs ├── TextDialog.Designer.cs ├── TextDialog.cs ├── TextDialog.resx ├── WorkDirDialog.Designer.cs ├── WorkDirDialog.cs ├── WorkDirDialog.resx ├── app.ico ├── color.json └── tab.png /.gitignore: -------------------------------------------------------------------------------- 1 | /*.suo 2 | /bin 3 | /obj 4 | /*.user 5 | -------------------------------------------------------------------------------- /App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ColorFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Text; 6 | using System.Web.Script.Serialization; 7 | using System.Windows.Forms; 8 | 9 | namespace ServiceMonitor 10 | { 11 | struct ColorDef 12 | { 13 | public string KeyWords; 14 | public Color C; 15 | public ColorDef( string keywords, Color c ) 16 | { 17 | C =c; 18 | KeyWords = keywords; 19 | } 20 | } 21 | 22 | class ColorFile 23 | { 24 | public List ColorTab = new List(); 25 | } 26 | 27 | class ColorSettings 28 | { 29 | static Dictionary _color2brush = new Dictionary(); 30 | 31 | public static Brush ColorToBrush( Color c ) 32 | { 33 | Brush b; 34 | if ( _color2brush.TryGetValue( c, out b ) ) 35 | { 36 | return b; 37 | } 38 | 39 | b = new SolidBrush(c); 40 | _color2brush[c] = b; 41 | 42 | return b; 43 | } 44 | 45 | static ColorFile _colorFile = new ColorFile(); 46 | 47 | public static void LoadColorTable(string filename) 48 | { 49 | var ser = new JavaScriptSerializer(); 50 | 51 | var content = File.ReadAllText(filename, Encoding.UTF8); 52 | 53 | try 54 | { 55 | _colorFile = ser.Deserialize(content); 56 | } 57 | catch (Exception e) 58 | { 59 | MessageBox.Show(e.ToString()); 60 | } 61 | } 62 | 63 | public static Color PickColorFromText(string text) 64 | { 65 | foreach (ColorDef tab in _colorFile.ColorTab) 66 | { 67 | if (text.IndexOf(tab.KeyWords) == -1) 68 | { 69 | continue; 70 | } 71 | 72 | return tab.C; 73 | } 74 | 75 | return Color.Gray; 76 | } 77 | } 78 | 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (C) 2016 davyxu 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /LogView.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Win32; 2 | using System; 3 | using System.Diagnostics; 4 | using System.Drawing; 5 | using System.IO; 6 | using System.Text; 7 | using System.Text.RegularExpressions; 8 | using System.Windows.Forms; 9 | 10 | namespace ServiceMonitor 11 | { 12 | public class LogView : ListBox 13 | { 14 | public LogView( ) 15 | { 16 | this.Dock = DockStyle.Fill; 17 | this.BackColor = Color.Black; 18 | this.DrawMode = DrawMode.OwnerDrawVariable; 19 | this.DrawItem += OnDrawItem; 20 | this.MouseDown += OnMouseDown; 21 | this.DoubleClick += OnDoubleClick; 22 | } 23 | 24 | public void AddLog( Color c, string text, bool autoscroll ) 25 | { 26 | int index = this.Items.Add(new LogData(c, text, this.Items.Count)); 27 | 28 | if ( autoscroll ) 29 | { 30 | TopIndex = index; 31 | } 32 | } 33 | 34 | public string AllLogToString() 35 | { 36 | var sb = new StringBuilder(); 37 | 38 | foreach (var item in Items) 39 | { 40 | sb.Append(item.ToString()); 41 | sb.Append("\n"); 42 | } 43 | 44 | return sb.ToString(); 45 | } 46 | 47 | private TabControl tabControl1; 48 | private TabPage tabPage1; 49 | 50 | static readonly SolidBrush textBg = new SolidBrush(Color.Black); 51 | 52 | void OnDrawItem(object sender, DrawItemEventArgs e) 53 | { 54 | if (e.Index == -1) 55 | return; 56 | 57 | LogData data = Items[e.Index] as LogData; // Get the current item and cast it to MyListBoxItem 58 | if (data != null) 59 | { 60 | e.Graphics.FillRectangle(textBg, e.Bounds); 61 | 62 | var brush = ColorSettings.ColorToBrush(data.FontColor); 63 | 64 | try 65 | { 66 | // 文本太长时, 这里会造成崩溃 67 | e.Graphics.DrawString( // Draw the appropriate text in the ListBox 68 | data.Text, // The message linked to the item 69 | Font, // Take the font from the listbox 70 | brush, // Set the color 71 | e.Bounds // Y pixel coordinate. Multiply the index by the ItemHeight defined in the listbox. 72 | ); 73 | } 74 | catch 75 | { 76 | 77 | } 78 | 79 | 80 | 81 | } 82 | else 83 | { 84 | // The item isn't a MyListBoxItem, do something about it 85 | } 86 | } 87 | 88 | void OnMouseDown(object sender, MouseEventArgs e) 89 | { 90 | try 91 | { 92 | this.SelectedIndex = IndexFromPoint(e.X, e.Y); 93 | } 94 | catch (Exception) 95 | { 96 | 97 | } 98 | 99 | } 100 | 101 | public static bool ParseLineText(string text, out string filename, out string line ) 102 | { 103 | var regex = new Regex(@"(?\w*:[/\S]*):(?\d*)", RegexOptions.IgnoreCase 104 | | RegexOptions.CultureInvariant 105 | | RegexOptions.IgnorePatternWhitespace 106 | | RegexOptions.Compiled); 107 | var result = regex.Match(text); 108 | if (result.Success) 109 | { 110 | filename = result.Groups["file"].Value; 111 | line = result.Groups["line"].Value; 112 | return true; 113 | } 114 | 115 | filename = ""; 116 | line = ""; 117 | 118 | return false; 119 | } 120 | 121 | static bool OpenFile(string filename, string line) 122 | { 123 | if (!File.Exists(filename)) 124 | return false; 125 | 126 | 127 | var nppDir = (string)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Notepad++", null, null); 128 | 129 | if ( string.IsNullOrEmpty(nppDir)) 130 | { 131 | nppDir = "c:\\Program Files (x86)\\Notepad++"; 132 | } 133 | 134 | var nppExePath = Path.Combine(nppDir, "Notepad++.exe"); 135 | Process.Start(nppExePath, string.Format("\"{0}\" -n{1}", filename, line)); 136 | 137 | return true; 138 | } 139 | 140 | void OnDoubleClick(object sender, EventArgs e) 141 | { 142 | var ee = e as MouseEventArgs; 143 | try 144 | { 145 | var listbox = sender as ListBox; 146 | this.SelectedIndex = IndexFromPoint(ee.X, ee.Y); 147 | 148 | var logdata = SelectedItem as LogData; 149 | 150 | string filename, line; 151 | if (!ParseLineText(logdata.Text, out filename, out line) || !OpenFile(filename, line)) 152 | { 153 | var dialog = new TextDialog(logdata.Text); 154 | dialog.ShowDialog(); 155 | } 156 | 157 | } 158 | catch (Exception) 159 | { 160 | 161 | } 162 | } 163 | 164 | public void EnsureVisible( int index ) 165 | { 166 | this.TopIndex = index; 167 | this.Refresh(); 168 | } 169 | 170 | private void InitializeComponent() 171 | { 172 | this.tabControl1 = new System.Windows.Forms.TabControl(); 173 | this.tabPage1 = new System.Windows.Forms.TabPage(); 174 | this.tabPage2 = new System.Windows.Forms.TabPage(); 175 | this.tabControl1.SuspendLayout(); 176 | this.SuspendLayout(); 177 | // 178 | // tabControl1 179 | // 180 | this.tabControl1.Controls.Add(this.tabPage1); 181 | this.tabControl1.Controls.Add(this.tabPage2); 182 | this.tabControl1.Location = new System.Drawing.Point(0, 0); 183 | this.tabControl1.Name = "tabControl1"; 184 | this.tabControl1.SelectedIndex = 0; 185 | this.tabControl1.Size = new System.Drawing.Size(200, 100); 186 | this.tabControl1.TabIndex = 0; 187 | // 188 | // tabPage1 189 | // 190 | this.tabPage1.Location = new System.Drawing.Point(0, 0); 191 | this.tabPage1.Name = "tabPage1"; 192 | this.tabPage1.Padding = new System.Windows.Forms.Padding(3); 193 | this.tabPage1.Size = new System.Drawing.Size(200, 100); 194 | this.tabPage1.TabIndex = 0; 195 | this.tabPage1.Text = "tabPage1"; 196 | this.tabPage1.UseVisualStyleBackColor = true; 197 | // 198 | // tabPage2 199 | // 200 | this.tabPage2.Location = new System.Drawing.Point(0, 0); 201 | this.tabPage2.Name = "tabPage2"; 202 | this.tabPage2.Padding = new System.Windows.Forms.Padding(3); 203 | this.tabPage2.Size = new System.Drawing.Size(200, 100); 204 | this.tabPage2.TabIndex = 1; 205 | this.tabPage2.Text = "tabPage2"; 206 | this.tabPage2.UseVisualStyleBackColor = true; 207 | this.tabControl1.ResumeLayout(false); 208 | this.ResumeLayout(false); 209 | 210 | } 211 | 212 | private TabPage tabPage2; 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /LogView.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 | 17, 17 122 | 123 | 124 | False 125 | 126 | -------------------------------------------------------------------------------- /MonitorController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Windows.Forms; 4 | using System.Linq; 5 | 6 | namespace ServiceMonitor 7 | { 8 | class MonitorController 9 | { 10 | public Func OnProcessCreate; 11 | 12 | Control _invoker; 13 | 14 | public static string TabFileName = "profile.json"; 15 | 16 | public MonitorController( MonitorView view ) 17 | { 18 | _invoker = view; 19 | } 20 | 21 | public void Init( ) 22 | { 23 | int index = 0; 24 | TabSettings.LoadSettings(TabFileName, (tab) => 25 | { 26 | AddProcess(tab ).Index = index ++ ; 27 | }); 28 | 29 | 30 | ColorSettings.LoadColorTable("color.json"); 31 | } 32 | 33 | public void Exit( ) 34 | { 35 | StopAllProcess(true); 36 | 37 | var list = new List(); 38 | 39 | var sortedModel = _modelByID.Values.ToList(); 40 | sortedModel.Sort((a , b) => 41 | { 42 | return a.Index < b.Index ? -1 : 1; 43 | }); 44 | 45 | foreach (ProcessModel model in sortedModel) 46 | { 47 | var tabInfo = new TabInfo(); 48 | tabInfo.OnSave(model); 49 | list.Add(tabInfo); 50 | } 51 | 52 | TabSettings.SaveSettings(TabFileName, list); 53 | 54 | 55 | } 56 | 57 | Dictionary _modelByID = new Dictionary(); 58 | 59 | public ProcessModel GetModelByObject(object obj) 60 | { 61 | if (obj == null) 62 | return null; 63 | 64 | ProcessModel model; 65 | if ( _modelByID.TryGetValue( obj, out model ) ) 66 | { 67 | return model; 68 | } 69 | 70 | return null; 71 | } 72 | 73 | 74 | public void StartAllProcess( ) 75 | { 76 | foreach( ProcessModel model in _modelByID.Values ) 77 | { 78 | if (model.ManualControl) 79 | continue; 80 | 81 | model.Start(); 82 | } 83 | } 84 | 85 | public void ClearAllProcessLog() 86 | { 87 | foreach (ProcessModel model in _modelByID.Values) 88 | { 89 | if (model.ManualControl) 90 | continue; 91 | 92 | model.ClearLog(); 93 | } 94 | } 95 | 96 | public void StopAllProcess(bool force) 97 | { 98 | foreach (ProcessModel model in _modelByID.Values) 99 | { 100 | if (!force && model.ManualControl) 101 | continue; 102 | 103 | model.Stop(); 104 | } 105 | } 106 | 107 | public ProcessModel AddProcess(TabInfo tab) 108 | { 109 | var model = new ProcessModel( ); 110 | model.invoker = _invoker; 111 | 112 | tab.OnLoad(model); 113 | 114 | var obj = OnProcessCreate( model ); 115 | 116 | _modelByID.Add(obj, model); 117 | 118 | return model; 119 | } 120 | 121 | public void RemoveProcess( object obj ) 122 | { 123 | _modelByID.Remove(obj); 124 | } 125 | 126 | 127 | 128 | 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /MonitorView.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ServiceMonitor 2 | { 3 | partial class MonitorView 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 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MonitorView)); 33 | this.tabMain = new System.Windows.Forms.TabControl(); 34 | this.logMenu = new System.Windows.Forms.ContextMenuStrip(this.components); 35 | this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripMenuItem(); 36 | this.ShowLneTextToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 37 | this.LogSaveToFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 38 | this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator(); 39 | this.BuildRunFToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 40 | this.BuildToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 41 | this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator(); 42 | this.SearchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 43 | this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); 44 | this.ClearToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 45 | this.ClearAllToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 46 | this.AutoScrollToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 47 | this.ManualStartToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 48 | this.label1 = new System.Windows.Forms.Label(); 49 | this.txtArgs = new System.Windows.Forms.TextBox(); 50 | this.btnWorkDir = new System.Windows.Forms.Button(); 51 | this.btnStartAll = new System.Windows.Forms.Button(); 52 | this.btnStart = new System.Windows.Forms.Button(); 53 | this.btnStopAll = new System.Windows.Forms.Button(); 54 | this.btnStop = new System.Windows.Forms.Button(); 55 | this.tabMenu = new System.Windows.Forms.ContextMenuStrip(this.components); 56 | this.CloseTabToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 57 | this.AddTabToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 58 | this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); 59 | this.MoveLeftToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 60 | this.MoveRightToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 61 | this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator(); 62 | this.CopyTabToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 63 | this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripSeparator(); 64 | this.OpenDirToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 65 | this.logMenu.SuspendLayout(); 66 | this.tabMenu.SuspendLayout(); 67 | this.SuspendLayout(); 68 | // 69 | // tabMain 70 | // 71 | this.tabMain.Location = new System.Drawing.Point(0, 0); 72 | this.tabMain.Name = "tabMain"; 73 | this.tabMain.SelectedIndex = 0; 74 | this.tabMain.Size = new System.Drawing.Size(804, 426); 75 | this.tabMain.TabIndex = 0; 76 | this.tabMain.SelectedIndexChanged += new System.EventHandler(this.tabMain_SelectedIndexChanged); 77 | // 78 | // logMenu 79 | // 80 | this.logMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 81 | this.toolStripMenuItem7, 82 | this.ShowLneTextToolStripMenuItem, 83 | this.LogSaveToFileToolStripMenuItem, 84 | this.toolStripMenuItem4, 85 | this.BuildRunFToolStripMenuItem, 86 | this.BuildToolStripMenuItem, 87 | this.toolStripMenuItem2, 88 | this.SearchToolStripMenuItem, 89 | this.toolStripMenuItem3, 90 | this.ClearToolStripMenuItem, 91 | this.ClearAllToolStripMenuItem, 92 | this.AutoScrollToolStripMenuItem, 93 | this.ManualStartToolStripMenuItem}); 94 | this.logMenu.Name = "contextMenuStrip1"; 95 | this.logMenu.Size = new System.Drawing.Size(160, 242); 96 | this.logMenu.Opening += new System.ComponentModel.CancelEventHandler(this.mnuTab_Opening); 97 | // 98 | // toolStripMenuItem7 99 | // 100 | this.toolStripMenuItem7.Name = "toolStripMenuItem7"; 101 | this.toolStripMenuItem7.Size = new System.Drawing.Size(159, 22); 102 | this.toolStripMenuItem7.Text = "复制行文字(&O)"; 103 | // 104 | // ShowLneTextToolStripMenuItem 105 | // 106 | this.ShowLneTextToolStripMenuItem.Name = "ShowLneTextToolStripMenuItem"; 107 | this.ShowLneTextToolStripMenuItem.Size = new System.Drawing.Size(159, 22); 108 | this.ShowLneTextToolStripMenuItem.Text = "显示行文字(&D)"; 109 | this.ShowLneTextToolStripMenuItem.Click += new System.EventHandler(this.ShowLineTextToolStripMenuItem_Click); 110 | // 111 | // LogSaveToFileToolStripMenuItem 112 | // 113 | this.LogSaveToFileToolStripMenuItem.Name = "LogSaveToFileToolStripMenuItem"; 114 | this.LogSaveToFileToolStripMenuItem.Size = new System.Drawing.Size(159, 22); 115 | this.LogSaveToFileToolStripMenuItem.Text = "日志保存文件..."; 116 | this.LogSaveToFileToolStripMenuItem.Click += new System.EventHandler(this.LogSaveToFileToolStripMenuItem_Click); 117 | // 118 | // toolStripMenuItem4 119 | // 120 | this.toolStripMenuItem4.Name = "toolStripMenuItem4"; 121 | this.toolStripMenuItem4.Size = new System.Drawing.Size(156, 6); 122 | // 123 | // BuildRunFToolStripMenuItem 124 | // 125 | this.BuildRunFToolStripMenuItem.Name = "BuildRunFToolStripMenuItem"; 126 | this.BuildRunFToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F5; 127 | this.BuildRunFToolStripMenuItem.Size = new System.Drawing.Size(159, 22); 128 | this.BuildRunFToolStripMenuItem.Text = "编译运行(&F)"; 129 | this.BuildRunFToolStripMenuItem.Click += new System.EventHandler(this.BuildRunFToolStripMenuItem_Click); 130 | // 131 | // BuildToolStripMenuItem 132 | // 133 | this.BuildToolStripMenuItem.Name = "BuildToolStripMenuItem"; 134 | this.BuildToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F7; 135 | this.BuildToolStripMenuItem.Size = new System.Drawing.Size(159, 22); 136 | this.BuildToolStripMenuItem.Text = "编译(&B)"; 137 | this.BuildToolStripMenuItem.Click += new System.EventHandler(this.BuildToolStripMenuItem_Click); 138 | // 139 | // toolStripMenuItem2 140 | // 141 | this.toolStripMenuItem2.Name = "toolStripMenuItem2"; 142 | this.toolStripMenuItem2.Size = new System.Drawing.Size(156, 6); 143 | // 144 | // SearchToolStripMenuItem 145 | // 146 | this.SearchToolStripMenuItem.Name = "SearchToolStripMenuItem"; 147 | this.SearchToolStripMenuItem.Size = new System.Drawing.Size(159, 22); 148 | this.SearchToolStripMenuItem.Text = "搜索(&S)"; 149 | this.SearchToolStripMenuItem.Click += new System.EventHandler(this.SearchToolStripMenuItem_Click); 150 | // 151 | // toolStripMenuItem3 152 | // 153 | this.toolStripMenuItem3.Name = "toolStripMenuItem3"; 154 | this.toolStripMenuItem3.Size = new System.Drawing.Size(156, 6); 155 | // 156 | // ClearToolStripMenuItem 157 | // 158 | this.ClearToolStripMenuItem.Name = "ClearToolStripMenuItem"; 159 | this.ClearToolStripMenuItem.Size = new System.Drawing.Size(159, 22); 160 | this.ClearToolStripMenuItem.Text = "清空(&L)"; 161 | this.ClearToolStripMenuItem.Click += new System.EventHandler(this.ClearToolStripMenuItem_Click); 162 | // 163 | // ClearAllToolStripMenuItem 164 | // 165 | this.ClearAllToolStripMenuItem.Name = "ClearAllToolStripMenuItem"; 166 | this.ClearAllToolStripMenuItem.Size = new System.Drawing.Size(159, 22); 167 | this.ClearAllToolStripMenuItem.Text = "清空所有(&J)"; 168 | this.ClearAllToolStripMenuItem.Click += new System.EventHandler(this.ClearAllToolStripMenuItem_Click); 169 | // 170 | // AutoScrollToolStripMenuItem 171 | // 172 | this.AutoScrollToolStripMenuItem.Name = "AutoScrollToolStripMenuItem"; 173 | this.AutoScrollToolStripMenuItem.Size = new System.Drawing.Size(159, 22); 174 | this.AutoScrollToolStripMenuItem.Text = "自动卷轴"; 175 | this.AutoScrollToolStripMenuItem.Click += new System.EventHandler(this.AutoScrollToolStripMenuItem_Click); 176 | // 177 | // ManualStartToolStripMenuItem 178 | // 179 | this.ManualStartToolStripMenuItem.Name = "ManualStartToolStripMenuItem"; 180 | this.ManualStartToolStripMenuItem.Size = new System.Drawing.Size(159, 22); 181 | this.ManualStartToolStripMenuItem.Text = "手动启动"; 182 | this.ManualStartToolStripMenuItem.Click += new System.EventHandler(this.ManualStartToolStripMenuItem_Click); 183 | // 184 | // label1 185 | // 186 | this.label1.AutoSize = true; 187 | this.label1.Location = new System.Drawing.Point(166, 441); 188 | this.label1.Name = "label1"; 189 | this.label1.Size = new System.Drawing.Size(59, 12); 190 | this.label1.TabIndex = 2; 191 | this.label1.Text = "启动参数:"; 192 | // 193 | // txtArgs 194 | // 195 | this.txtArgs.Location = new System.Drawing.Point(231, 438); 196 | this.txtArgs.Name = "txtArgs"; 197 | this.txtArgs.Size = new System.Drawing.Size(323, 21); 198 | this.txtArgs.TabIndex = 1; 199 | this.txtArgs.TextChanged += new System.EventHandler(this.txtArgs_TextChanged); 200 | // 201 | // btnWorkDir 202 | // 203 | this.btnWorkDir.Location = new System.Drawing.Point(560, 436); 204 | this.btnWorkDir.Name = "btnWorkDir"; 205 | this.btnWorkDir.Size = new System.Drawing.Size(75, 23); 206 | this.btnWorkDir.TabIndex = 0; 207 | this.btnWorkDir.Text = "工作目录"; 208 | this.btnWorkDir.UseVisualStyleBackColor = true; 209 | this.btnWorkDir.Click += new System.EventHandler(this.btnSetWorkDir_Click); 210 | // 211 | // btnStartAll 212 | // 213 | this.btnStartAll.Location = new System.Drawing.Point(641, 436); 214 | this.btnStartAll.Name = "btnStartAll"; 215 | this.btnStartAll.Size = new System.Drawing.Size(75, 23); 216 | this.btnStartAll.TabIndex = 0; 217 | this.btnStartAll.Text = "启动所有"; 218 | this.btnStartAll.UseVisualStyleBackColor = true; 219 | this.btnStartAll.Click += new System.EventHandler(this.btnStartAll_Click); 220 | // 221 | // btnStart 222 | // 223 | this.btnStart.Location = new System.Drawing.Point(6, 436); 224 | this.btnStart.Name = "btnStart"; 225 | this.btnStart.Size = new System.Drawing.Size(75, 23); 226 | this.btnStart.TabIndex = 0; 227 | this.btnStart.Text = "启动"; 228 | this.btnStart.UseVisualStyleBackColor = true; 229 | this.btnStart.Click += new System.EventHandler(this.btnStart_Click); 230 | // 231 | // btnStopAll 232 | // 233 | this.btnStopAll.Location = new System.Drawing.Point(720, 436); 234 | this.btnStopAll.Name = "btnStopAll"; 235 | this.btnStopAll.Size = new System.Drawing.Size(75, 23); 236 | this.btnStopAll.TabIndex = 0; 237 | this.btnStopAll.Text = "停止所有"; 238 | this.btnStopAll.UseVisualStyleBackColor = true; 239 | this.btnStopAll.Click += new System.EventHandler(this.btnStopAll_Click); 240 | // 241 | // btnStop 242 | // 243 | this.btnStop.Location = new System.Drawing.Point(87, 436); 244 | this.btnStop.Name = "btnStop"; 245 | this.btnStop.Size = new System.Drawing.Size(75, 23); 246 | this.btnStop.TabIndex = 0; 247 | this.btnStop.Text = "停止"; 248 | this.btnStop.UseVisualStyleBackColor = true; 249 | this.btnStop.Click += new System.EventHandler(this.btnStop_Click); 250 | // 251 | // tabMenu 252 | // 253 | this.tabMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 254 | this.CloseTabToolStripMenuItem, 255 | this.AddTabToolStripMenuItem, 256 | this.toolStripMenuItem1, 257 | this.MoveLeftToolStripMenuItem, 258 | this.MoveRightToolStripMenuItem, 259 | this.toolStripMenuItem5, 260 | this.CopyTabToolStripMenuItem, 261 | this.toolStripMenuItem6, 262 | this.OpenDirToolStripMenuItem}); 263 | this.tabMenu.Name = "tabMenu"; 264 | this.tabMenu.Size = new System.Drawing.Size(166, 154); 265 | // 266 | // CloseTabToolStripMenuItem 267 | // 268 | this.CloseTabToolStripMenuItem.Name = "CloseTabToolStripMenuItem"; 269 | this.CloseTabToolStripMenuItem.Size = new System.Drawing.Size(165, 22); 270 | this.CloseTabToolStripMenuItem.Text = "关闭(&X)"; 271 | this.CloseTabToolStripMenuItem.Click += new System.EventHandler(this.CloseTabToolStripMenuItem_Click); 272 | // 273 | // AddTabToolStripMenuItem 274 | // 275 | this.AddTabToolStripMenuItem.Name = "AddTabToolStripMenuItem"; 276 | this.AddTabToolStripMenuItem.Size = new System.Drawing.Size(165, 22); 277 | this.AddTabToolStripMenuItem.Text = "添加(&A)"; 278 | this.AddTabToolStripMenuItem.Click += new System.EventHandler(this.AddTabToolStripMenuItem_Click); 279 | // 280 | // toolStripMenuItem1 281 | // 282 | this.toolStripMenuItem1.Name = "toolStripMenuItem1"; 283 | this.toolStripMenuItem1.Size = new System.Drawing.Size(162, 6); 284 | // 285 | // MoveLeftToolStripMenuItem 286 | // 287 | this.MoveLeftToolStripMenuItem.Name = "MoveLeftToolStripMenuItem"; 288 | this.MoveLeftToolStripMenuItem.Size = new System.Drawing.Size(165, 22); 289 | this.MoveLeftToolStripMenuItem.Text = "左移(&L)"; 290 | this.MoveLeftToolStripMenuItem.Click += new System.EventHandler(this.MoveLeftToolStripMenuItem_Click); 291 | // 292 | // MoveRightToolStripMenuItem 293 | // 294 | this.MoveRightToolStripMenuItem.Name = "MoveRightToolStripMenuItem"; 295 | this.MoveRightToolStripMenuItem.Size = new System.Drawing.Size(165, 22); 296 | this.MoveRightToolStripMenuItem.Text = "右移(&R)"; 297 | this.MoveRightToolStripMenuItem.Click += new System.EventHandler(this.MoveRightToolStripMenuItem_Click); 298 | // 299 | // toolStripMenuItem5 300 | // 301 | this.toolStripMenuItem5.Name = "toolStripMenuItem5"; 302 | this.toolStripMenuItem5.Size = new System.Drawing.Size(162, 6); 303 | // 304 | // CopyTabToolStripMenuItem 305 | // 306 | this.CopyTabToolStripMenuItem.Name = "CopyTabToolStripMenuItem"; 307 | this.CopyTabToolStripMenuItem.Size = new System.Drawing.Size(165, 22); 308 | this.CopyTabToolStripMenuItem.Text = "复制(&C)"; 309 | this.CopyTabToolStripMenuItem.Click += new System.EventHandler(this.CopyTabToolStripMenuItem_Click); 310 | // 311 | // toolStripMenuItem6 312 | // 313 | this.toolStripMenuItem6.Name = "toolStripMenuItem6"; 314 | this.toolStripMenuItem6.Size = new System.Drawing.Size(162, 6); 315 | // 316 | // OpenDirToolStripMenuItem 317 | // 318 | this.OpenDirToolStripMenuItem.Name = "OpenDirToolStripMenuItem"; 319 | this.OpenDirToolStripMenuItem.Size = new System.Drawing.Size(165, 22); 320 | this.OpenDirToolStripMenuItem.Text = "打开目标目录(&D)"; 321 | this.OpenDirToolStripMenuItem.Click += new System.EventHandler(this.OpenDirToolStripMenuItem_Click_1); 322 | // 323 | // MonitorView 324 | // 325 | this.AllowDrop = true; 326 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 327 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 328 | this.BackColor = System.Drawing.SystemColors.Control; 329 | this.ClientSize = new System.Drawing.Size(805, 467); 330 | this.Controls.Add(this.txtArgs); 331 | this.Controls.Add(this.btnStop); 332 | this.Controls.Add(this.label1); 333 | this.Controls.Add(this.btnStopAll); 334 | this.Controls.Add(this.btnStart); 335 | this.Controls.Add(this.btnStartAll); 336 | this.Controls.Add(this.btnWorkDir); 337 | this.Controls.Add(this.tabMain); 338 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 339 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 340 | this.MaximizeBox = false; 341 | this.Name = "MonitorView"; 342 | this.Text = "ServiceMonitor 2.4.6"; 343 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); 344 | this.Load += new System.EventHandler(this.MainForm_Load); 345 | this.DragDrop += new System.Windows.Forms.DragEventHandler(this.MainForm_DragDrop); 346 | this.DragEnter += new System.Windows.Forms.DragEventHandler(this.MainForm_DragEnter); 347 | this.logMenu.ResumeLayout(false); 348 | this.tabMenu.ResumeLayout(false); 349 | this.ResumeLayout(false); 350 | this.PerformLayout(); 351 | 352 | } 353 | 354 | #endregion 355 | 356 | private System.Windows.Forms.TabControl tabMain; 357 | private System.Windows.Forms.Button btnStartAll; 358 | private System.Windows.Forms.Button btnStart; 359 | private System.Windows.Forms.Button btnStopAll; 360 | private System.Windows.Forms.Button btnStop; 361 | private System.Windows.Forms.ContextMenuStrip logMenu; 362 | private System.Windows.Forms.Label label1; 363 | private System.Windows.Forms.TextBox txtArgs; 364 | private System.Windows.Forms.ToolStripMenuItem ClearToolStripMenuItem; 365 | private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2; 366 | private System.Windows.Forms.ToolStripMenuItem ShowLneTextToolStripMenuItem; 367 | private System.Windows.Forms.ToolStripMenuItem LogSaveToFileToolStripMenuItem; 368 | private System.Windows.Forms.ToolStripMenuItem ClearAllToolStripMenuItem; 369 | private System.Windows.Forms.ToolStripMenuItem AutoScrollToolStripMenuItem; 370 | private System.Windows.Forms.ToolStripMenuItem SearchToolStripMenuItem; 371 | private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3; 372 | private System.Windows.Forms.ToolStripMenuItem BuildToolStripMenuItem; 373 | private System.Windows.Forms.ToolStripMenuItem BuildRunFToolStripMenuItem; 374 | private System.Windows.Forms.ToolStripSeparator toolStripMenuItem4; 375 | private System.Windows.Forms.ContextMenuStrip tabMenu; 376 | private System.Windows.Forms.ToolStripMenuItem CloseTabToolStripMenuItem; 377 | private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5; 378 | private System.Windows.Forms.ToolStripMenuItem CopyTabToolStripMenuItem; 379 | private System.Windows.Forms.ToolStripSeparator toolStripMenuItem6; 380 | private System.Windows.Forms.ToolStripMenuItem OpenDirToolStripMenuItem; 381 | private System.Windows.Forms.ToolStripMenuItem AddTabToolStripMenuItem; 382 | private System.Windows.Forms.ToolStripMenuItem ManualStartToolStripMenuItem; 383 | private System.Windows.Forms.Button btnWorkDir; 384 | private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; 385 | private System.Windows.Forms.ToolStripMenuItem MoveLeftToolStripMenuItem; 386 | private System.Windows.Forms.ToolStripMenuItem MoveRightToolStripMenuItem; 387 | private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem7; 388 | } 389 | } 390 | 391 | -------------------------------------------------------------------------------- /MonitorView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Windows.Forms; 6 | 7 | namespace ServiceMonitor 8 | { 9 | public partial class MonitorView : Form 10 | { 11 | MonitorController _controller; 12 | 13 | public MonitorView() 14 | { 15 | _controller = new MonitorController(this); 16 | _controller.OnProcessCreate += OnProcessCreate; 17 | 18 | InitializeComponent(); 19 | 20 | PaintTabControl(); 21 | 22 | } 23 | 24 | void PaintTabControl() 25 | { 26 | tabMain.DrawMode = TabDrawMode.OwnerDrawFixed; 27 | tabMain.DrawItem += (sender, e) => 28 | { 29 | var model = SafeGetModel(tabMain.TabPages[e.Index]); 30 | 31 | Rectangle myTabRect = tabMain.GetTabRect(e.Index); 32 | 33 | Brush textBrush = null; 34 | Brush bgBrush = null; 35 | 36 | if ( model.Running ) 37 | { 38 | bgBrush = ColorSettings.ColorToBrush(Color.Green); 39 | textBrush = ColorSettings.ColorToBrush(Color.White); 40 | } 41 | else if (model.SelfExit) 42 | { 43 | bgBrush = ColorSettings.ColorToBrush(Color.Red); 44 | textBrush = ColorSettings.ColorToBrush(Color.White); 45 | } 46 | 47 | 48 | if (e.Index == tabMain.SelectedIndex) 49 | { 50 | textBrush = ColorSettings.ColorToBrush(Color.White); 51 | bgBrush = ColorSettings.ColorToBrush(Color.Black); 52 | } 53 | else if (textBrush == null) 54 | { 55 | textBrush = ColorSettings.ColorToBrush(Color.Black); 56 | } 57 | 58 | if (bgBrush != null ) 59 | { 60 | e.Graphics.FillRectangle(bgBrush, myTabRect); 61 | } 62 | 63 | 64 | //先添加TabPage属性 65 | e.Graphics.DrawString(tabMain.TabPages[e.Index].Text, this.Font, textBrush, myTabRect.X + 2, myTabRect.Y + 2); 66 | 67 | }; 68 | } 69 | 70 | 71 | 72 | #region Model获取封装,基础功能封装 73 | 74 | ProcessModel SafeGetModel(object obj) 75 | { 76 | var model = _controller.GetModelByObject(obj); 77 | if (model == null) 78 | { 79 | return new ProcessModel(); 80 | } 81 | 82 | return model; 83 | } 84 | 85 | ProcessModel SafeGetCurrTableModel() 86 | { 87 | return SafeGetModel(tabMain.SelectedTab); 88 | } 89 | 90 | // 命名规则: 与svc同目录下, svc.exe 对应的批处理是 svc_Build.bat 91 | void RunSvcShell(ProcessModel svcModel, bool startAfterDone) 92 | { 93 | if (!svcModel.Valid) 94 | return; 95 | 96 | // 还在跑的进程, 必须停下来 97 | if (svcModel.Running) 98 | { 99 | svcModel.Stop(); 100 | } 101 | 102 | var buildcmd = Path.Combine(Path.GetDirectoryName(svcModel.FileName), Path.GetFileNameWithoutExtension(svcModel.FileName) + "_Build") + ".bat"; 103 | 104 | var shellModel = new ProcessModel(); 105 | shellModel.FileName = buildcmd; 106 | shellModel.invoker = this; 107 | shellModel.CanStop = false; 108 | 109 | shellModel.OnStart += (m) => 110 | { 111 | m.WriteLog(Color.Yellow, "启动Shell: " + buildcmd); 112 | }; 113 | 114 | Action stopProc = (m) => 115 | { 116 | m.WriteLog(Color.Yellow, "结束Shell: " + buildcmd); 117 | 118 | // 编译正常时, 启动进程 119 | if (startAfterDone && shellModel.ExitCode == 0) 120 | { 121 | svcModel.Start(); 122 | } 123 | }; 124 | 125 | 126 | shellModel.OnStop += stopProc; 127 | shellModel.OnExit += stopProc; 128 | 129 | shellModel.OnLog += svcModel.OnLog; 130 | shellModel.OnError += svcModel.OnError; 131 | 132 | shellModel.Start(); 133 | 134 | RefreshButtonStatus(); 135 | } 136 | 137 | #endregion 138 | 139 | #region Process创建,开启,关闭行为 140 | 141 | object OnProcessCreate(ProcessModel model) 142 | { 143 | var name = Path.GetFileNameWithoutExtension(model.FileName); 144 | 145 | var page = new TabPage(name); 146 | page.ContextMenuStrip = logMenu; 147 | var logview = new LogView(); 148 | page.ToolTipText = model.FileName; 149 | 150 | page.Controls.Add(logview); 151 | tabMain.TabPages.Add(page); 152 | 153 | model.Index = tabMain.TabPages.IndexOf(page); 154 | 155 | tabMain.SelectedTab = page; 156 | tabMain.MouseClick += (sender, e) => 157 | { 158 | if ( e.Button == System.Windows.Forms.MouseButtons.Right ) 159 | { 160 | tabMenu.Show(tabMain, e.Location); 161 | } 162 | }; 163 | 164 | Action logProc = (m, c, data) => 165 | { 166 | logview.AddLog(c, data, model.AutoScroll); 167 | }; 168 | 169 | model.OnStart += OnProcessStart; 170 | model.OnStop += OnProcessStop; 171 | model.OnExit += OnProcessExit; 172 | 173 | model.OnLog += logProc; 174 | model.OnError += logProc; 175 | model.view = logview; 176 | 177 | model.OnClear += delegate() 178 | { 179 | logview.Items.Clear(); 180 | }; 181 | 182 | model.OnGetData += ( index ) => 183 | { 184 | return logview.Items[index] as LogData; 185 | }; 186 | 187 | 188 | model.OnGetDataCount += ( ) => 189 | { 190 | return logview.Items.Count; 191 | }; 192 | 193 | model.OnGetAllLog += delegate() 194 | { 195 | return logview.AllLogToString(); 196 | }; 197 | 198 | model.OnGetSelectedContent += delegate() 199 | { 200 | var logdata = logview.SelectedItem as LogData; 201 | if (logdata == null) 202 | return string.Empty; 203 | 204 | return logdata.Text; 205 | }; 206 | 207 | model.WriteLog(Color.Yellow, "就绪"); 208 | 209 | return page; 210 | } 211 | 212 | 213 | void OnProcessStart(ProcessModel model ) 214 | { 215 | model.WriteLog(Color.Yellow, "进程启动 "); 216 | 217 | RefreshButtonStatus(); 218 | 219 | tabMain.Refresh(); 220 | } 221 | 222 | void OnProcessStop(ProcessModel model) 223 | { 224 | tabMain.Refresh(); 225 | } 226 | 227 | void OnProcessExit(ProcessModel model) 228 | { 229 | RefreshButtonStatus(); 230 | 231 | tabMain.Refresh(); 232 | 233 | model.WriteLog(Color.Yellow, string.Format("进程结束({0})", model.ExitCode) ); 234 | } 235 | 236 | 237 | #endregion 238 | 239 | #region 主面板MainForm及按钮行为 240 | 241 | void MainForm_Load(object sender, EventArgs e) 242 | { 243 | _controller.Init(); 244 | } 245 | 246 | 247 | private void MainForm_DragDrop(object sender, DragEventArgs e) 248 | { 249 | string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); 250 | foreach (string file in files) 251 | { 252 | 253 | _controller.AddProcess(new TabInfo { FileName = file }); 254 | } 255 | } 256 | private void MainForm_DragEnter(object sender, DragEventArgs e) 257 | { 258 | if (e.Data.GetDataPresent(DataFormats.FileDrop, false)) 259 | { 260 | e.Effect = DragDropEffects.All; 261 | } 262 | 263 | } 264 | 265 | private void MainForm_FormClosing(object sender, FormClosingEventArgs e) 266 | { 267 | _controller.Exit(); 268 | } 269 | 270 | 271 | private void btnStart_Click(object sender, EventArgs e) 272 | { 273 | SafeGetCurrTableModel().Start(); 274 | 275 | RefreshButtonStatus(); 276 | } 277 | 278 | private void btnStop_Click(object sender, EventArgs e) 279 | { 280 | SafeGetCurrTableModel().Stop(); 281 | 282 | RefreshButtonStatus(); 283 | } 284 | private void btnStartAll_Click(object sender, EventArgs e) 285 | { 286 | _controller.StartAllProcess(); 287 | 288 | RefreshButtonStatus(); 289 | } 290 | 291 | private void btnStopAll_Click(object sender, EventArgs e) 292 | { 293 | _controller.StopAllProcess(false); 294 | 295 | RefreshButtonStatus(); 296 | } 297 | 298 | private void tabMain_SelectedIndexChanged(object sender, EventArgs e) 299 | { 300 | RefreshButtonStatus(); 301 | } 302 | 303 | private void btnSetWorkDir_Click(object sender, EventArgs e) 304 | { 305 | var model = SafeGetCurrTableModel(); 306 | 307 | var dialog = new WorkDirDialog(model.WorkDir); 308 | if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) 309 | { 310 | model.WorkDir = dialog.WorkDir; 311 | } 312 | } 313 | 314 | bool _disableTextNotify; 315 | void RefreshButtonStatus( ) 316 | { 317 | var pm = SafeGetCurrTableModel(); 318 | 319 | btnStart.Enabled = !pm.Running; 320 | 321 | if ( pm.CanStop ) 322 | { 323 | btnStop.Enabled = pm.Running; 324 | } 325 | else 326 | { 327 | btnStop.Enabled = false; 328 | } 329 | 330 | 331 | _disableTextNotify = true; 332 | txtArgs.Text = pm.Args; 333 | _disableTextNotify = false; 334 | } 335 | 336 | 337 | private void txtArgs_TextChanged(object sender, EventArgs e) 338 | { 339 | if (_disableTextNotify) 340 | return; 341 | 342 | SafeGetCurrTableModel().Args = txtArgs.Text; 343 | } 344 | 345 | private void btnClear_Click(object sender, EventArgs e) 346 | { 347 | SafeGetCurrTableModel().ClearLog(); 348 | } 349 | 350 | #endregion 351 | 352 | #region 日志菜单 353 | 354 | private void ClearToolStripMenuItem_Click(object sender, EventArgs e) 355 | { 356 | SafeGetCurrTableModel().ClearLog(); 357 | } 358 | 359 | 360 | private void CopyLineTextToolStripMenuItem_Click(object sender, EventArgs e) 361 | { 362 | 363 | var text = SafeGetCurrTableModel().GetSelectedContext(); 364 | Clipboard.SetText(text); 365 | } 366 | 367 | private void ShowLineTextToolStripMenuItem_Click(object sender, EventArgs e) 368 | { 369 | var text = SafeGetCurrTableModel().GetSelectedContext(); 370 | 371 | var dialog = new TextDialog(text); 372 | dialog.ShowDialog(); 373 | } 374 | 375 | private void LogSaveToFileToolStripMenuItem_Click(object sender, EventArgs e) 376 | { 377 | SaveFileDialog dialog = new SaveFileDialog(); 378 | dialog.Filter = " txt files(*.txt)|*.txt|All files(*.*)|*.*"; 379 | dialog.RestoreDirectory = true ; 380 | if ( dialog.ShowDialog( ) == System.Windows.Forms.DialogResult.OK ) 381 | { 382 | File.WriteAllText(dialog.FileName, SafeGetCurrTableModel().GetAllLog() ); 383 | 384 | } 385 | } 386 | 387 | private void ClearAllToolStripMenuItem_Click(object sender, EventArgs e) 388 | { 389 | _controller.ClearAllProcessLog(); 390 | } 391 | 392 | private void AutoScrollToolStripMenuItem_Click(object sender, EventArgs e) 393 | { 394 | var item = sender as ToolStripMenuItem; 395 | item.Checked = !item.Checked; 396 | 397 | SafeGetCurrTableModel( ).AutoScroll = item.Checked; 398 | } 399 | 400 | private void ManualStartToolStripMenuItem_Click(object sender, EventArgs e) 401 | { 402 | var item = sender as ToolStripMenuItem; 403 | item.Checked = !item.Checked; 404 | 405 | SafeGetCurrTableModel().ManualControl = item.Checked; 406 | } 407 | 408 | 409 | private void mnuTab_Opening(object sender, System.ComponentModel.CancelEventArgs e) 410 | { 411 | var model = SafeGetCurrTableModel(); 412 | if (!string.IsNullOrEmpty(model.FileName)) 413 | { 414 | AutoScrollToolStripMenuItem.Checked = model.AutoScroll; 415 | ManualStartToolStripMenuItem.Checked = model.ManualControl; 416 | SearchToolStripMenuItem.Enabled = _search == null; 417 | } 418 | 419 | } 420 | 421 | SearchDialog _search; 422 | 423 | private void SearchToolStripMenuItem_Click(object sender, EventArgs e) 424 | { 425 | if (_search != null) 426 | return; 427 | 428 | _search = new SearchDialog( SafeGetCurrTableModel() ); 429 | _search.FormClosed += (s, ee) => 430 | { 431 | _search = null; 432 | }; 433 | _search.Show(this); 434 | } 435 | 436 | // 编译并运行 437 | private void BuildRunFToolStripMenuItem_Click(object sender, EventArgs e) 438 | { 439 | RunSvcShell(SafeGetCurrTableModel(), true); 440 | } 441 | 442 | // 编译 443 | private void BuildToolStripMenuItem_Click(object sender, EventArgs e) 444 | { 445 | RunSvcShell(SafeGetCurrTableModel(), false); 446 | } 447 | 448 | #endregion 449 | 450 | #region Tab菜单 451 | 452 | private void AddTabToolStripMenuItem_Click(object sender, EventArgs e) 453 | { 454 | OpenFileDialog dialog = new OpenFileDialog(); 455 | dialog.Filter = "exe files (*.exe)|*.exe|bat files(*.bat)|*.bat"; 456 | dialog.FilterIndex = 1; 457 | dialog.RestoreDirectory = true; 458 | 459 | if (dialog.ShowDialog() == DialogResult.OK) 460 | { 461 | _controller.AddProcess(new TabInfo { FileName = dialog.FileName }); 462 | } 463 | } 464 | 465 | private void CloseTabToolStripMenuItem_Click(object sender, EventArgs e) 466 | { 467 | var tab = tabMain.SelectedTab; 468 | if (tab != null) 469 | { 470 | SafeGetCurrTableModel().Stop(); 471 | 472 | tabMain.TabPages.Remove(tab); 473 | _controller.RemoveProcess(tab); 474 | } 475 | } 476 | 477 | private void CopyTabToolStripMenuItem_Click(object sender, EventArgs e) 478 | { 479 | var model = SafeGetCurrTableModel(); 480 | if (!string.IsNullOrEmpty(model.FileName)) 481 | { 482 | var tabinfo = new TabInfo { FileName = model.FileName, Args = model.Args, ManualControl = model.ManualControl }; 483 | _controller.AddProcess(tabinfo); 484 | } 485 | } 486 | 487 | private void OpenDirToolStripMenuItem_Click_1(object sender, EventArgs e) 488 | { 489 | var model = SafeGetCurrTableModel(); 490 | if (!string.IsNullOrEmpty(model.FileName)) 491 | { 492 | Process.Start("explorer.exe", Path.GetDirectoryName(model.FileName)); 493 | } 494 | } 495 | 496 | 497 | private void MoveLeftToolStripMenuItem_Click(object sender, EventArgs e) 498 | { 499 | MoveTab(-1); 500 | } 501 | 502 | private void MoveRightToolStripMenuItem_Click(object sender, EventArgs e) 503 | { 504 | MoveTab(1); 505 | } 506 | 507 | void MoveTab(int delta) 508 | { 509 | var index = tabMain.SelectedIndex; 510 | 511 | if ( index >= tabMain.TabPages.Count - 1 && delta > 0 ) 512 | { 513 | return; 514 | } 515 | 516 | if ( index <= 0 && delta < 0 ) 517 | { 518 | return; 519 | } 520 | 521 | var tab = tabMain.SelectedTab; 522 | 523 | tabMain.TabPages.RemoveAt(index); 524 | 525 | tabMain.TabPages.Insert(index + delta, tab); 526 | tabMain.SelectedIndex = index + delta; 527 | 528 | // 与谁换 529 | var slibing = SafeGetModel(tabMain.TabPages[index]); 530 | // 更新索引 531 | slibing.Index = index; 532 | 533 | // 主动换的人更新索引 534 | var model = SafeGetCurrTableModel(); 535 | model.Index = tabMain.TabPages.IndexOf(tab); 536 | 537 | } 538 | 539 | 540 | 541 | #endregion 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | } 562 | } 563 | -------------------------------------------------------------------------------- /PathUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Runtime.InteropServices; 4 | using System.Text; 5 | 6 | namespace ServiceMonitor 7 | { 8 | class PathUtil 9 | { 10 | public static string GetRelativePath(string fromPath, string toPath) 11 | { 12 | int fromAttr = GetPathAttribute(fromPath); 13 | int toAttr = GetPathAttribute(toPath); 14 | 15 | StringBuilder path = new StringBuilder(260); // MAX_PATH 16 | if (PathRelativePathTo( 17 | path, 18 | fromPath, 19 | fromAttr, 20 | toPath, 21 | toAttr) == 0) 22 | { 23 | throw new ArgumentException("Paths must have a common prefix"); 24 | } 25 | return path.ToString(); 26 | } 27 | 28 | private static int GetPathAttribute(string path) 29 | { 30 | DirectoryInfo di = new DirectoryInfo(path); 31 | if (di.Exists) 32 | { 33 | return FILE_ATTRIBUTE_DIRECTORY; 34 | } 35 | 36 | FileInfo fi = new FileInfo(path); 37 | if (fi.Exists) 38 | { 39 | return FILE_ATTRIBUTE_NORMAL; 40 | } 41 | 42 | throw new FileNotFoundException(); 43 | } 44 | 45 | private const int FILE_ATTRIBUTE_DIRECTORY = 0x10; 46 | private const int FILE_ATTRIBUTE_NORMAL = 0x80; 47 | 48 | [DllImport("shlwapi.dll", SetLastError = true)] 49 | private static extern int PathRelativePathTo(StringBuilder pszPath, 50 | string pszFrom, int dwAttrFrom, string pszTo, int dwAttrTo); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /ProcessModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Windows.Forms; 8 | 9 | namespace ServiceMonitor 10 | { 11 | public class LogData 12 | { 13 | string _text; 14 | Color _color; 15 | int _index; 16 | 17 | public LogData(Color c, string text, int index ) 18 | { 19 | _color = c; 20 | _text = text; 21 | _index = index; 22 | } 23 | 24 | public int Index 25 | { 26 | get { return _index; } 27 | } 28 | 29 | public string Text 30 | { 31 | get { return _text; } 32 | } 33 | public Color FontColor 34 | { 35 | get { return _color; } 36 | } 37 | 38 | public override string ToString() 39 | { 40 | return _text; 41 | } 42 | 43 | } 44 | 45 | public class ProcessModel 46 | { 47 | Process _process; 48 | bool _manualStop; 49 | 50 | public Control invoker; 51 | 52 | public LogView view; 53 | 54 | public Action OnStart; 55 | 56 | public Action OnStop; 57 | 58 | public Action OnExit; 59 | 60 | public Action OnClear; 61 | 62 | public Func OnGetData; 63 | public Func OnGetDataCount; 64 | 65 | public Func OnGetAllLog; 66 | 67 | public Func OnGetSelectedContent; 68 | 69 | public Action OnLog; 70 | 71 | public Action OnError; 72 | 73 | public bool Valid 74 | { 75 | get { return !string.IsNullOrEmpty(FileName); } 76 | } 77 | 78 | public int PID 79 | { 80 | get { 81 | if (_process == null) 82 | return 0; 83 | 84 | return _process.Id; 85 | } 86 | } 87 | 88 | public string FileName{get;set;} 89 | 90 | public string Args{get;set;} 91 | 92 | public string WorkDir { get; set; } 93 | 94 | public bool AutoScroll { get; set; } 95 | 96 | public bool ManualControl { get; set; } 97 | 98 | // 可停止的, shell不能停止, 因为可能是里面的另外进程在允许 99 | public bool CanStop { get; set; } 100 | 101 | public int ExitCode { get; set; } 102 | 103 | // 在tabmain里的顺序 104 | public int Index { get; set; } 105 | 106 | // 进程自己 107 | public bool SelfExit { get; set; } 108 | 109 | public ProcessModel( ) 110 | { 111 | CanStop = true; 112 | AutoScroll = true; 113 | } 114 | 115 | public bool Running { get; set; } 116 | 117 | public void ClearLog( ) 118 | { 119 | OnClear( ); 120 | } 121 | 122 | public LogData GetData( int index ) 123 | { 124 | return OnGetData( index); 125 | } 126 | 127 | public int GetDataCount( ) 128 | { 129 | return OnGetDataCount(); 130 | } 131 | 132 | public string GetAllLog( ) 133 | { 134 | return OnGetAllLog( ); 135 | } 136 | 137 | public string GetSelectedContext() 138 | { 139 | return OnGetSelectedContent(); 140 | } 141 | 142 | public void Start() 143 | { 144 | if (Running) 145 | return; 146 | 147 | _manualStop = false; 148 | 149 | Running = true; 150 | 151 | var info = new ProcessStartInfo(FileName); 152 | 153 | info.Arguments = Args; 154 | info.RedirectStandardOutput = true; 155 | info.RedirectStandardError = true; 156 | info.RedirectStandardInput = true; 157 | info.StandardErrorEncoding = Encoding.UTF8; 158 | info.StandardOutputEncoding = Encoding.UTF8; 159 | info.UseShellExecute = false; 160 | info.CreateNoWindow = true; 161 | if (string.IsNullOrEmpty(WorkDir)) 162 | { 163 | info.WorkingDirectory = Path.GetDirectoryName(FileName); 164 | } 165 | else 166 | { 167 | info.WorkingDirectory = WorkDir; 168 | } 169 | 170 | 171 | ThreadPool.QueueUserWorkItem(delegate(object state) 172 | { 173 | 174 | SafeCall( delegate { 175 | 176 | if (OnStart != null) 177 | { 178 | OnStart(this); 179 | } 180 | }); 181 | 182 | Process p = null; 183 | try 184 | { 185 | p = Process.Start(info); 186 | _process = p; 187 | } 188 | catch (Exception e) 189 | { 190 | SafeCall( delegate { 191 | OnError( this, Color.Red, e.ToString() ); 192 | 193 | }); 194 | } 195 | 196 | if (p != null) 197 | { 198 | p.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) 199 | { 200 | if (e.Data == null) 201 | return; 202 | 203 | var c = ColorSettings.PickColorFromText(e.Data); 204 | 205 | SafeCall( delegate { 206 | 207 | WriteLog(c, e.Data); 208 | }); 209 | }; 210 | 211 | p.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e) 212 | { 213 | if (e.Data == null) 214 | return; 215 | 216 | var c = ColorSettings.PickColorFromText(e.Data); 217 | 218 | SafeCall( delegate { 219 | 220 | WriteLog(c, e.Data); 221 | }); 222 | }; 223 | 224 | p.BeginOutputReadLine(); 225 | p.BeginErrorReadLine(); 226 | 227 | Application.DoEvents(); 228 | p.WaitForExit(); 229 | 230 | ExitCode = p.ExitCode; 231 | 232 | p.Close(); 233 | } 234 | 235 | 236 | SafeCall(delegate 237 | { 238 | if (!_manualStop) 239 | { 240 | SelfExit = true; 241 | } 242 | 243 | if (OnExit != null) 244 | { 245 | OnExit(this ); 246 | } 247 | }); 248 | 249 | _process = null; 250 | Running = false; 251 | 252 | 253 | }); 254 | } 255 | 256 | public void WriteLog(Color c, string text) 257 | { 258 | if ( OnLog != null ) 259 | { 260 | OnLog(this, c, text); 261 | } 262 | } 263 | 264 | delegate void InvokeHandler( Action callback ); 265 | void SafeCall(Action callback ) 266 | { 267 | 268 | if (invoker != null && invoker.InvokeRequired) 269 | { 270 | invoker.BeginInvoke(new InvokeHandler(SafeCall), callback); 271 | } 272 | else 273 | { 274 | callback( ); 275 | } 276 | } 277 | 278 | public void Stop() 279 | { 280 | if (!Running) 281 | { 282 | return; 283 | } 284 | 285 | _manualStop = true; 286 | 287 | 288 | Running = false; 289 | 290 | if (_process == null) 291 | return; 292 | 293 | try 294 | { 295 | _process.Kill(); 296 | } 297 | catch(Exception e ) 298 | { 299 | Debug.WriteLine(e.ToString()); 300 | } 301 | 302 | if (OnStop != null ) 303 | { 304 | OnStop(this); 305 | } 306 | 307 | } 308 | 309 | } 310 | } 311 | -------------------------------------------------------------------------------- /Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace ServiceMonitor 5 | { 6 | static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | /// 12 | 13 | [STAThread] 14 | static void Main() 15 | { 16 | 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new MonitorView()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using System.Resources; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("ServiceMonitor")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("ServiceMonitor")] 14 | [assembly: AssemblyCopyright("Copyright © 2015")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | [assembly: Guid("80c20326-68d3-43ab-8445-34e2f059da27")] 25 | 26 | // Version information for an assembly consists of the following four values: 27 | // 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("1.0.0.0")] 37 | [assembly: AssemblyFileVersion("1.0.0.0")] 38 | [assembly: NeutralResourcesLanguageAttribute("zh-CN")] 39 | -------------------------------------------------------------------------------- /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 ServiceMonitor.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("ServiceMonitor.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 | -------------------------------------------------------------------------------- /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 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /Properties/TabSettings.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 ServiceMonitor.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] 16 | internal sealed partial class TabSettings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static TabSettings defaultInstance = ((TabSettings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new TabSettings()))); 19 | 20 | public static TabSettings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Properties/TabSettings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 方便的服务器进程管理器 2 | ![截图](tab.png) 3 | 4 | # 基本功能 5 | 6 | 启动参数设置 7 | 8 | 工作目录设置 9 | 10 | 打开进程目录 11 | 12 | 日志搜索 13 | 14 | # 特性 15 | 16 | ## 批量启动,手动启动 17 | 18 | 一键启动所有服务器 19 | 20 | 对单个服务器可以设置手动启动不跟随一键启动 21 | 22 | ## 挂接命令行实现"编译并运行" 23 | 24 | 使用golang的服务器 25 | 26 | 在进程同目录准备"进程名_Build.bat"批处理, 填入如下参数 27 | 28 | ```bat 29 | set GOPATH=GOPATH目录 30 | go install -v 进程名 31 | ``` 32 | 33 | 在tab的日志中, 点击右键, 选择"编译"或"编译并运行" 34 | 35 | 如果编译成功, 将马上运行进程, 否则将停止运行批处理 36 | 37 | 38 | ## 日志自定义加色 39 | 编辑color.json, 每一行日志的颜色匹配优先度从高到低 40 | 41 | 使用方法: 42 | 43 | 将color.json与ServiceMonitor.exe在同目录 44 | 45 | ## 进程状态颜色标记 46 | 47 | 进程运行时, 自动变绿 48 | 49 | 进程崩溃时, 自动变红 50 | 51 | 52 | # 备注 53 | 54 | 感觉不错请star, 谢谢! 55 | 56 | 博客: http://www.cppblog.com/sunicdavy 57 | 58 | 知乎: http://www.zhihu.com/people/sunicdavy 59 | 60 | bug,特性提交: https://github.com/davyxu/ServiceMonitor/issues 61 | 62 | 代码贡献: https://github.com/davyxu/ServiceMonitor/pulls 63 | 64 | -------------------------------------------------------------------------------- /SearchDialog.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ServiceMonitor 2 | { 3 | partial class SearchDialog 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 | this.txtMain = new System.Windows.Forms.TextBox(); 32 | this.resultList = new System.Windows.Forms.ListBox(); 33 | this.splitContainer1 = new System.Windows.Forms.SplitContainer(); 34 | this.search = new System.Windows.Forms.Button(); 35 | this.caseSense = new System.Windows.Forms.CheckBox(); 36 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); 37 | this.splitContainer1.Panel1.SuspendLayout(); 38 | this.splitContainer1.Panel2.SuspendLayout(); 39 | this.splitContainer1.SuspendLayout(); 40 | this.SuspendLayout(); 41 | // 42 | // txtMain 43 | // 44 | this.txtMain.Dock = System.Windows.Forms.DockStyle.Fill; 45 | this.txtMain.Location = new System.Drawing.Point(0, 0); 46 | this.txtMain.Name = "txtMain"; 47 | this.txtMain.Size = new System.Drawing.Size(537, 21); 48 | this.txtMain.TabIndex = 0; 49 | this.txtMain.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.txtMain_KeyPress); 50 | // 51 | // resultList 52 | // 53 | this.resultList.Dock = System.Windows.Forms.DockStyle.Fill; 54 | this.resultList.FormattingEnabled = true; 55 | this.resultList.ItemHeight = 12; 56 | this.resultList.Location = new System.Drawing.Point(0, 0); 57 | this.resultList.Name = "resultList"; 58 | this.resultList.Size = new System.Drawing.Size(537, 239); 59 | this.resultList.TabIndex = 1; 60 | this.resultList.DoubleClick += new System.EventHandler(this.resultList_DoubleClick); 61 | // 62 | // splitContainer1 63 | // 64 | this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; 65 | this.splitContainer1.Location = new System.Drawing.Point(0, 0); 66 | this.splitContainer1.Name = "splitContainer1"; 67 | this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; 68 | // 69 | // splitContainer1.Panel1 70 | // 71 | this.splitContainer1.Panel1.Controls.Add(this.search); 72 | this.splitContainer1.Panel1.Controls.Add(this.caseSense); 73 | this.splitContainer1.Panel1.Controls.Add(this.txtMain); 74 | // 75 | // splitContainer1.Panel2 76 | // 77 | this.splitContainer1.Panel2.Controls.Add(this.resultList); 78 | this.splitContainer1.Size = new System.Drawing.Size(537, 299); 79 | this.splitContainer1.SplitterDistance = 56; 80 | this.splitContainer1.TabIndex = 2; 81 | // 82 | // search 83 | // 84 | this.search.Location = new System.Drawing.Point(459, 24); 85 | this.search.Name = "search"; 86 | this.search.Size = new System.Drawing.Size(75, 23); 87 | this.search.TabIndex = 2; 88 | this.search.Text = "搜索"; 89 | this.search.UseVisualStyleBackColor = true; 90 | this.search.Click += new System.EventHandler(this.search_Click); 91 | // 92 | // caseSense 93 | // 94 | this.caseSense.AutoSize = true; 95 | this.caseSense.Location = new System.Drawing.Point(13, 28); 96 | this.caseSense.Name = "caseSense"; 97 | this.caseSense.Size = new System.Drawing.Size(84, 16); 98 | this.caseSense.TabIndex = 1; 99 | this.caseSense.Text = "区分大小写"; 100 | this.caseSense.UseVisualStyleBackColor = true; 101 | // 102 | // SearchDialog 103 | // 104 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 105 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 106 | this.ClientSize = new System.Drawing.Size(537, 299); 107 | this.Controls.Add(this.splitContainer1); 108 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; 109 | this.Name = "SearchDialog"; 110 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 111 | this.Text = "搜索"; 112 | this.splitContainer1.Panel1.ResumeLayout(false); 113 | this.splitContainer1.Panel1.PerformLayout(); 114 | this.splitContainer1.Panel2.ResumeLayout(false); 115 | ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); 116 | this.splitContainer1.ResumeLayout(false); 117 | this.ResumeLayout(false); 118 | 119 | } 120 | 121 | #endregion 122 | 123 | private System.Windows.Forms.TextBox txtMain; 124 | private System.Windows.Forms.ListBox resultList; 125 | private System.Windows.Forms.SplitContainer splitContainer1; 126 | private System.Windows.Forms.Button search; 127 | private System.Windows.Forms.CheckBox caseSense; 128 | } 129 | } -------------------------------------------------------------------------------- /SearchDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace ServiceMonitor 12 | { 13 | public partial class SearchDialog : Form 14 | { 15 | ProcessModel _model; 16 | 17 | public SearchDialog( ProcessModel model ) 18 | { 19 | InitializeComponent(); 20 | splitContainer1.IsSplitterFixed = true; 21 | 22 | _model = model; 23 | } 24 | 25 | public string Content 26 | { 27 | get { return txtMain.Text; } 28 | } 29 | 30 | void SearchText( string text, bool caseSense ) 31 | { 32 | 33 | string textToSearch = text.Trim(); 34 | if (caseSense ) 35 | { 36 | textToSearch = text.Trim().ToLower(); 37 | } 38 | 39 | resultList.BeginUpdate(); 40 | resultList.Items.Clear(); 41 | 42 | if ( textToSearch != "") 43 | { 44 | int count = _model.GetDataCount(); 45 | 46 | for (int i = 0; i < count; i++) 47 | { 48 | var item = _model.GetData(i); 49 | if (item.Text.IndexOf(textToSearch) != -1) 50 | { 51 | resultList.Items.Add(item); 52 | } 53 | } 54 | } 55 | 56 | resultList.EndUpdate(); 57 | } 58 | 59 | private void txtMain_KeyPress(object sender, KeyPressEventArgs e) 60 | { 61 | if ( e.KeyChar == (char)13) 62 | { 63 | SearchText(txtMain.Text, caseSense.Checked ); 64 | } 65 | } 66 | 67 | private void search_Click(object sender, EventArgs e) 68 | { 69 | SearchText(txtMain.Text, caseSense.Checked); 70 | } 71 | 72 | private void resultList_DoubleClick(object sender, EventArgs e) 73 | { 74 | var ee = e as MouseEventArgs; 75 | 76 | resultList.SelectedIndex = resultList.IndexFromPoint(ee.X, ee.Y); 77 | 78 | var item = resultList.SelectedItem as LogData; 79 | 80 | if ( item != null ) 81 | { 82 | _model.view.EnsureVisible(item.Index); 83 | } 84 | 85 | 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /SearchDialog.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 | -------------------------------------------------------------------------------- /ServiceMonitor.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {9B93DD6E-2FA3-4030-AB7B-37C79CC92C6E} 8 | WinExe 9 | Properties 10 | ServiceMonitor 11 | ServiceMonitor 12 | v4.5 13 | 512 14 | publish\ 15 | true 16 | Disk 17 | false 18 | Foreground 19 | 7 20 | Days 21 | false 22 | false 23 | true 24 | 0 25 | 1.0.0.%2a 26 | false 27 | false 28 | true 29 | 30 | 31 | 32 | AnyCPU 33 | true 34 | full 35 | false 36 | bin\Debug\ 37 | DEBUG;TRACE 38 | prompt 39 | 4 40 | false 41 | 42 | 43 | AnyCPU 44 | pdbonly 45 | true 46 | bin\Release\ 47 | TRACE 48 | prompt 49 | 4 50 | false 51 | 52 | 53 | app.ico 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | Component 72 | 73 | 74 | 75 | Form 76 | 77 | 78 | MonitorView.cs 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | Form 87 | 88 | 89 | SearchDialog.cs 90 | 91 | 92 | Form 93 | 94 | 95 | WorkDirDialog.cs 96 | 97 | 98 | Form 99 | 100 | 101 | TextDialog.cs 102 | 103 | 104 | LogView.cs 105 | 106 | 107 | MonitorView.cs 108 | 109 | 110 | ResXFileCodeGenerator 111 | Resources.Designer.cs 112 | Designer 113 | 114 | 115 | True 116 | Resources.resx 117 | True 118 | 119 | 120 | SearchDialog.cs 121 | 122 | 123 | WorkDirDialog.cs 124 | 125 | 126 | TextDialog.cs 127 | 128 | 129 | SettingsSingleFileGenerator 130 | TabSettings.Designer.cs 131 | 132 | 133 | True 134 | TabSettings.settings 135 | True 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | False 147 | Microsoft .NET Framework 4.5 %28x86 and x64%29 148 | true 149 | 150 | 151 | False 152 | .NET Framework 3.5 SP1 Client Profile 153 | false 154 | 155 | 156 | False 157 | .NET Framework 3.5 SP1 158 | false 159 | 160 | 161 | 162 | 169 | -------------------------------------------------------------------------------- /ServiceMonitor.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceMonitor", "ServiceMonitor.csproj", "{9B93DD6E-2FA3-4030-AB7B-37C79CC92C6E}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {9B93DD6E-2FA3-4030-AB7B-37C79CC92C6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {9B93DD6E-2FA3-4030-AB7B-37C79CC92C6E}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {9B93DD6E-2FA3-4030-AB7B-37C79CC92C6E}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {9B93DD6E-2FA3-4030-AB7B-37C79CC92C6E}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /TabSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text; 5 | using System.Web.Script.Serialization; 6 | using System.Windows.Forms; 7 | 8 | namespace ServiceMonitor 9 | { 10 | struct TabInfo 11 | { 12 | public string FileName; 13 | public string Args; 14 | public bool ManualControl; 15 | public string WorkDir; 16 | 17 | public void OnLoad( ProcessModel model ) 18 | { 19 | 20 | model.FileName = Path.GetFullPath(this.FileName); 21 | model.Args = this.Args; 22 | model.ManualControl = this.ManualControl; 23 | model.WorkDir = this.WorkDir; 24 | } 25 | 26 | public void OnSave( ProcessModel model ) 27 | { 28 | try 29 | { 30 | this.FileName = PathUtil.GetRelativePath(Application.StartupPath, model.FileName); 31 | } 32 | catch (Exception ex) 33 | { 34 | MessageBox.Show(ex.Message); 35 | } 36 | 37 | this.Args = model.Args; 38 | this.ManualControl = model.ManualControl; 39 | this.WorkDir = model.WorkDir; 40 | } 41 | } 42 | 43 | class Profile 44 | { 45 | public List Tabs = new List(); 46 | } 47 | 48 | class TabSettings 49 | { 50 | public static void LoadSettings(string filename, Action callback ) 51 | { 52 | var ser = new JavaScriptSerializer(); 53 | 54 | string content = string.Empty; 55 | try 56 | { 57 | content = File.ReadAllText(filename, Encoding.UTF8); 58 | } 59 | catch (Exception) 60 | { 61 | 62 | } 63 | 64 | Profile profile; 65 | 66 | try 67 | { 68 | profile = ser.Deserialize(content); 69 | } 70 | catch (Exception) 71 | { 72 | return; 73 | } 74 | 75 | if (profile == null) 76 | { 77 | return; 78 | } 79 | 80 | 81 | foreach (var tabInfo in profile.Tabs) 82 | { 83 | callback(tabInfo); 84 | } 85 | } 86 | 87 | 88 | 89 | public static void SaveSettings(string filename, List list ) 90 | { 91 | 92 | var profile = new Profile(); 93 | 94 | profile.Tabs = list; 95 | 96 | var ser = new JavaScriptSerializer(); 97 | var content = ser.Serialize(profile); 98 | 99 | File.WriteAllText(filename, content, Encoding.UTF8); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /TextDialog.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ServiceMonitor 2 | { 3 | partial class TextDialog 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 | this.txtMain = new System.Windows.Forms.TextBox(); 32 | this.SuspendLayout(); 33 | // 34 | // txtMain 35 | // 36 | this.txtMain.Dock = System.Windows.Forms.DockStyle.Fill; 37 | this.txtMain.Location = new System.Drawing.Point(0, 0); 38 | this.txtMain.Multiline = true; 39 | this.txtMain.Name = "txtMain"; 40 | this.txtMain.ReadOnly = true; 41 | this.txtMain.Size = new System.Drawing.Size(466, 211); 42 | this.txtMain.TabIndex = 0; 43 | // 44 | // TextDialog 45 | // 46 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 47 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 48 | this.ClientSize = new System.Drawing.Size(466, 211); 49 | this.Controls.Add(this.txtMain); 50 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; 51 | this.Name = "TextDialog"; 52 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 53 | this.Text = "显示内容"; 54 | this.Load += new System.EventHandler(this.frmDialog_Load); 55 | this.ResumeLayout(false); 56 | this.PerformLayout(); 57 | 58 | } 59 | 60 | #endregion 61 | 62 | private System.Windows.Forms.TextBox txtMain; 63 | } 64 | } -------------------------------------------------------------------------------- /TextDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace ServiceMonitor 5 | { 6 | public partial class TextDialog : Form 7 | { 8 | public TextDialog(string txt) 9 | { 10 | InitializeComponent(); 11 | 12 | txtMain.Text = txt; 13 | } 14 | 15 | private void frmDialog_Load(object sender, EventArgs e) 16 | { 17 | 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /TextDialog.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 | -------------------------------------------------------------------------------- /WorkDirDialog.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ServiceMonitor 2 | { 3 | partial class WorkDirDialog 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 | this.txtMain = new System.Windows.Forms.TextBox(); 32 | this.btnOK = new System.Windows.Forms.Button(); 33 | this.panel1 = new System.Windows.Forms.Panel(); 34 | this.panel2 = new System.Windows.Forms.Panel(); 35 | this.btnCancel = new System.Windows.Forms.Button(); 36 | this.label1 = new System.Windows.Forms.Label(); 37 | this.panel1.SuspendLayout(); 38 | this.panel2.SuspendLayout(); 39 | this.SuspendLayout(); 40 | // 41 | // txtMain 42 | // 43 | this.txtMain.Dock = System.Windows.Forms.DockStyle.Fill; 44 | this.txtMain.Location = new System.Drawing.Point(0, 0); 45 | this.txtMain.Multiline = true; 46 | this.txtMain.Name = "txtMain"; 47 | this.txtMain.Size = new System.Drawing.Size(393, 26); 48 | this.txtMain.TabIndex = 0; 49 | // 50 | // btnOK 51 | // 52 | this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 53 | this.btnOK.Location = new System.Drawing.Point(191, 2); 54 | this.btnOK.Name = "btnOK"; 55 | this.btnOK.Size = new System.Drawing.Size(92, 24); 56 | this.btnOK.TabIndex = 1; 57 | this.btnOK.Text = "确定"; 58 | this.btnOK.UseVisualStyleBackColor = true; 59 | this.btnOK.Click += new System.EventHandler(this.btnOK_Click); 60 | // 61 | // panel1 62 | // 63 | this.panel1.Controls.Add(this.txtMain); 64 | this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; 65 | this.panel1.Location = new System.Drawing.Point(0, 0); 66 | this.panel1.Name = "panel1"; 67 | this.panel1.Size = new System.Drawing.Size(393, 26); 68 | this.panel1.TabIndex = 2; 69 | // 70 | // panel2 71 | // 72 | this.panel2.Controls.Add(this.label1); 73 | this.panel2.Controls.Add(this.btnCancel); 74 | this.panel2.Controls.Add(this.btnOK); 75 | this.panel2.Dock = System.Windows.Forms.DockStyle.Bottom; 76 | this.panel2.Location = new System.Drawing.Point(0, 26); 77 | this.panel2.Name = "panel2"; 78 | this.panel2.Size = new System.Drawing.Size(393, 29); 79 | this.panel2.TabIndex = 3; 80 | // 81 | // btnCancel 82 | // 83 | this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 84 | this.btnCancel.Location = new System.Drawing.Point(289, 2); 85 | this.btnCancel.Name = "btnCancel"; 86 | this.btnCancel.Size = new System.Drawing.Size(92, 24); 87 | this.btnCancel.TabIndex = 2; 88 | this.btnCancel.Text = "取消"; 89 | this.btnCancel.UseVisualStyleBackColor = true; 90 | this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); 91 | // 92 | // label1 93 | // 94 | this.label1.AutoSize = true; 95 | this.label1.Location = new System.Drawing.Point(12, 8); 96 | this.label1.Name = "label1"; 97 | this.label1.Size = new System.Drawing.Size(107, 12); 98 | this.label1.TabIndex = 3; 99 | this.label1.Text = "使用exe路径请留空"; 100 | // 101 | // WorkDirDialog 102 | // 103 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 104 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 105 | this.ClientSize = new System.Drawing.Size(393, 55); 106 | this.Controls.Add(this.panel1); 107 | this.Controls.Add(this.panel2); 108 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; 109 | this.Name = "WorkDirDialog"; 110 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 111 | this.Text = "工作路径"; 112 | this.Load += new System.EventHandler(this.frmDialog_Load); 113 | this.panel1.ResumeLayout(false); 114 | this.panel1.PerformLayout(); 115 | this.panel2.ResumeLayout(false); 116 | this.panel2.PerformLayout(); 117 | this.ResumeLayout(false); 118 | 119 | } 120 | 121 | #endregion 122 | 123 | private System.Windows.Forms.TextBox txtMain; 124 | private System.Windows.Forms.Button btnOK; 125 | private System.Windows.Forms.Panel panel1; 126 | private System.Windows.Forms.Panel panel2; 127 | private System.Windows.Forms.Button btnCancel; 128 | private System.Windows.Forms.Label label1; 129 | } 130 | } -------------------------------------------------------------------------------- /WorkDirDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace ServiceMonitor 5 | { 6 | public partial class WorkDirDialog : Form 7 | { 8 | public WorkDirDialog( string txt ) 9 | { 10 | InitializeComponent(); 11 | 12 | txtMain.Text = txt; 13 | } 14 | 15 | public string WorkDir 16 | { 17 | get { return txtMain.Text; } 18 | } 19 | 20 | private void frmDialog_Load(object sender, EventArgs e) 21 | { 22 | 23 | } 24 | 25 | private void btnOK_Click(object sender, EventArgs e) 26 | { 27 | this.DialogResult = System.Windows.Forms.DialogResult.OK; 28 | this.Close(); 29 | } 30 | 31 | private void btnCancel_Click(object sender, EventArgs e) 32 | { 33 | this.Close(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /WorkDirDialog.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 | -------------------------------------------------------------------------------- /app.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davyxu/ServiceMonitor/ea2f8785e570a4ffa952a818d7528d35b425ba34/app.ico -------------------------------------------------------------------------------- /color.json: -------------------------------------------------------------------------------- 1 | { 2 | "ColorTableLink": "http://blog.163.com/xiao_mege/blog/static/72942753201010152043161/", 3 | "ColorTab":[ 4 | {"KeyWords":"panic:","C":"Red"}, 5 | {"KeyWords":"[ERROR]","C":"Red"}, 6 | {"KeyWords":"[FATAL]","C":"Red"}, 7 | {"KeyWords":"[WARN]","C":"Yellow"}, 8 | {"KeyWords":"[DB]","C":"LimeGreen"}, 9 | {"KeyWords":"[Action]","C":"Coral"}, 10 | {"KeyWords":"[Event]","C":"DodgerBlue"}, 11 | {"KeyWords":"#recv","C":"MediumOrchid"}, 12 | {"KeyWords":"#send","C":"RosyBrown"}, 13 | {"KeyWords":"#connected","C":"CadetBlue"}, 14 | {"KeyWords":"#listen","C":"Moccasin"}, 15 | {"KeyWords":"#accepted","C":"CadetBlue"}, 16 | {"KeyWords":"#postpacket","C":"Thistle"}, 17 | {"KeyWords":"#closed","C":"DarkGoldenrod"}, 18 | {"KeyWords":"agent->backend","C":"MediumOrchid"}, 19 | {"KeyWords":"backend->agent","C":"RosyBrown"}, 20 | {"KeyWords":"client->backend","C":"MediumOrchid"}, 21 | {"KeyWords":"backend->client","C":"RosyBrown"}, 22 | 23 | 24 | {"KeyWords":"[DEBUG]","C":"LightGray"}, 25 | {"KeyWords":"[D]","C":"LightGray"} 26 | 27 | ] 28 | } -------------------------------------------------------------------------------- /tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davyxu/ServiceMonitor/ea2f8785e570a4ffa952a818d7528d35b425ba34/tab.png --------------------------------------------------------------------------------