├── .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