diff --git a/trunk/CHANGELOG.txt b/trunk/CHANGELOG.txt index 555f5715d..9d397f820 100644 --- a/trunk/CHANGELOG.txt +++ b/trunk/CHANGELOG.txt @@ -16,7 +16,10 @@ Process Hacker * #2657138 - "Add a toolbar" * #2657143 - "Add Changelog in Help menu" * #2675859 - "Log: auto-scroll option" + * #2675864 - "System Information improvements" * #2675871 - "Suggest file extension everywhere" + * Full CPU, I/O and memory usage history for processes and the OS + * Tooltips for graphs * Modules tab shows mapped files * "Reduce Working Set" function * Can change virtualization for processes diff --git a/trunk/ProcessHacker/Components/Plotter.Designer.cs b/trunk/ProcessHacker/Components/Plotter.Designer.cs index 19b25a4db..9350da62c 100644 --- a/trunk/ProcessHacker/Components/Plotter.Designer.cs +++ b/trunk/ProcessHacker/Components/Plotter.Designer.cs @@ -32,19 +32,32 @@ /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); + this.toolTip = new System.Windows.Forms.ToolTip(this.components); this.SuspendLayout(); // + // toolTip + // + this.toolTip.AutomaticDelay = 0; + this.toolTip.ShowAlways = true; + // // Plotter // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Name = "Plotter"; + this.Size = new System.Drawing.Size(150, 163); + this.MouseLeave += new System.EventHandler(this.Plotter_MouseLeave); this.Paint += new System.Windows.Forms.PaintEventHandler(this.Plotter_Paint); + this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Plotter_MouseMove); this.Resize += new System.EventHandler(this.Plotter_Resize); + this.MouseEnter += new System.EventHandler(this.Plotter_MouseEnter); this.ResumeLayout(false); } #endregion + + private System.Windows.Forms.ToolTip toolTip; } } diff --git a/trunk/ProcessHacker/Components/Plotter.cs b/trunk/ProcessHacker/Components/Plotter.cs index 9c590a77b..3126380d4 100644 --- a/trunk/ProcessHacker/Components/Plotter.cs +++ b/trunk/ProcessHacker/Components/Plotter.cs @@ -34,9 +34,14 @@ namespace ProcessHacker.Components { public partial class Plotter : UserControl { + public delegate string GetToolTipDelegate(int item); + private const BufferedGraphics NO_MANAGED_BACK_BUFFER = null; private BufferedGraphicsContext _graphicManager; private BufferedGraphics _managedBackBuffer; + private bool _showToolTip; + private Point _mouseLocation; + private string _lastToolTip; public Plotter() { @@ -49,12 +54,12 @@ namespace ProcessHacker.Components _managedBackBuffer = _graphicManager.Allocate(this.CreateGraphics(), this.ClientRectangle); - Draw(); + this.Draw(); } + public GetToolTipDelegate GetToolTip; + private int _gridStartPos = 0; - private List _listData1 = new List(); - private List _listData2 = new List(); private void Plotter_Paint(object sender, PaintEventArgs e) { @@ -62,7 +67,7 @@ namespace ProcessHacker.Components _managedBackBuffer.Render(e.Graphics); } - private void Draw() + public void Draw() { int tWidth = this.Width; int tHeight = this.Height; @@ -95,16 +100,25 @@ namespace ProcessHacker.Components } } + if (_useLongData && (_longData1 == null || (this.UseSecondLine && _longData2 == null))) + return; + + if (_useLongData) + this.FixLongData(); + + if (_data1 == null || (this.UseSecondLine && _data2 == null)) + return; + //draw lines int px = tWidth - _moveStep; - int start = _listData1.Count - 2; + int start = 0; Pen lGrid1 = new Pen(_lineColor1); Pen lGrid2 = new Pen(_lineColor2); - while (start >= 0) + while (start < _data1.Count - 1) { - float f = _listData1[start]; - float fPre = _listData1[start + 1]; + float f = _data1[start + 1]; + float fPre = _data1[start]; int h = (int)(tHeight - (tHeight * f)); int hPre = (int)(tHeight - (tHeight * fPre)); @@ -117,13 +131,13 @@ namespace ProcessHacker.Components if (this.UseSecondLine) { - f = _listData2[start]; - fPre = _listData2[start + 1]; + f = _data2[start + 1]; + fPre = _data2[start]; if (!this.OverlaySecondLine) { - f += _listData1[start]; - fPre += _listData1[start + 1]; + f += _data1[start + 1]; + fPre += _data1[start]; if (f > 1.0f) f = 1.0f; @@ -146,8 +160,8 @@ namespace ProcessHacker.Components { g.FillPolygon(new SolidBrush(Color.FromArgb(100, _lineColor2)), new Point[] { new Point(px, h), new Point(px + _moveStep, hPre), - new Point(px + _moveStep, tHeight - (int)(tHeight * _listData1[start + 1])), - new Point(px, tHeight - (int)(tHeight * _listData1[start])) }); + new Point(px + _moveStep, tHeight - (int)(tHeight * _data1[start])), + new Point(px, tHeight - (int)(tHeight * _data1[start + 1])) }); g.DrawLine(lGrid2, px, h, px + _moveStep, hPre); } } @@ -158,11 +172,11 @@ namespace ProcessHacker.Components } px -= _moveStep; - start--; + start++; } // draw text - if (this.Text != "" && this.Text != null) + if (this.Text != null && this.Text != "") { // draw the background for the text g.FillRectangle(new SolidBrush(_textBoxColor), @@ -172,116 +186,87 @@ namespace ProcessHacker.Components TextRenderer.DrawText(g, this.Text, this.Font, _textPosition, _textColor); } + if (_showToolTip) + this.ShowToolTip(); + this.Refresh(); } - /// - /// reset - /// - public void Reset() + private void ShowToolTip() { - _gridStartPos = 0; - _listData1.Clear(); - _listData2.Clear(); - Draw(); + this.ShowToolTip(false); } - /// - /// Adds two numbers to the lists of data. The numbers represent a fraction - /// of the plotter's height. - /// - /// A floating-point number less than or equal to 1. - /// A floating-point number less than or equal to 1. - public void Add(float f1, float f2) + private void ShowToolTip(bool force) { - if (f1 > 1.0f) - f1 = 1.0f; - if (f2 > 1.0f) - f2 = 1.0f; - if (f1 < 0.0f || float.IsNaN(f1)) - f1 = 0.0f; - if (f2 < 0.0f || float.IsNaN(f2)) - f2 = 0.0f; - - _listData1.Add(f1); - _listData2.Add(f2); - - if (_listData1.Count > this.ClientRectangle.Width / this.MoveStep + 1) - _listData1.RemoveRange(0, _listData1.Count - 1 - this.ClientRectangle.Width / this.MoveStep); - if (_listData2.Count > this.ClientRectangle.Width / this.MoveStep + 1) - _listData2.RemoveRange(0, _listData2.Count - 1 - this.ClientRectangle.Width / this.MoveStep); - - if (_isMoved) + if (this.GetToolTip != null) { - _gridStartPos += _moveStep; - if (_gridStartPos >= _gridSize.Width) + int itemIndex = (this.Width - _mouseLocation.X) / _moveStep; + + if (itemIndex < this.Data1.Count) { - _gridStartPos -= _gridSize.Width; + try + { + string currentToolTip = this.GetToolTip(itemIndex); + + if (currentToolTip != _lastToolTip || force) + toolTip.Show(currentToolTip, this, + new Point(_mouseLocation.X + 10, _mouseLocation.Y + 10), + int.MaxValue); + + _lastToolTip = currentToolTip; + } + catch + { } + } + else + { + toolTip.Hide(this); } } - - this.Draw(); } - private List _listRawData1 = new List(); - private List _listRawData2 = new List(); - - /// - /// Adds two numbers to the lists of data. The numbers are raw values, and - /// the graph will be automatically scaled to fit the largest value. - /// - /// A long. - /// A long. - public void Add(long v1, long v2) + public void MoveGrid() { - _listRawData1.Add(v1); - _listRawData2.Add(v2); + _gridStartPos += _moveStep; - if (_listRawData1.Count > this.ClientRectangle.Width / this.MoveStep + 1) - _listRawData1.RemoveRange(0, _listRawData1.Count - 1 - this.ClientRectangle.Width / this.MoveStep); - if (_listRawData2.Count > this.ClientRectangle.Width / this.MoveStep + 1) - _listRawData2.RemoveRange(0, _listRawData2.Count - 1 - this.ClientRectangle.Width / this.MoveStep); + if (_gridStartPos >= _gridSize.Width) + { + _gridStartPos -= _gridSize.Width; + } + } + public void FixLongData() + { // find the largest value long max = 0; - foreach (long l in _listRawData1) + foreach (long l in _longData1) if (l > max) max = l; - foreach (long l in _listRawData2) + foreach (long l in _longData2) if (l > max) max = l; - // redo the other list - _listData1.Clear(); - _listData2.Clear(); + // redo the float list + _data1 = new List(); + _data2 = new List(); - foreach (long l in _listRawData1) + foreach (long l in _longData1) { if (max != 0) - _listData1.Add((float)l / max); + _data1.Add((float)l / max); else - _listData1.Add(0); + _data1.Add(0); } - foreach (long l in _listRawData2) + foreach (long l in _longData2) { if (max != 0) - _listData2.Add((float)l / max); + _data2.Add((float)l / max); else - _listData2.Add(0); + _data2.Add(0); } - - if (_isMoved) - { - _gridStartPos += _moveStep; - if (_gridStartPos >= _gridSize.Width) - { - _gridStartPos -= _gridSize.Width; - } - } - - this.Draw(); } #region Text @@ -372,8 +357,6 @@ namespace ProcessHacker.Components _textPosition = new Point( _boxPosition.X + _textPadding.Left, _boxPosition.Y + _textPadding.Top); - - this.Draw(); } } @@ -438,11 +421,39 @@ namespace ProcessHacker.Components set { _moveStep = value; } } - private bool _isMoved = true; - public bool IsMoved + private IList _data1; + public IList Data1 { - get { return _isMoved; } - set { _isMoved = value; } + get { return _data1; } + set { _data1 = value; } + } + + private IList _data2; + public IList Data2 + { + get { return _data2; } + set { _data2 = value; } + } + + private bool _useLongData; + public bool UseLongData + { + get { return _useLongData; } + set { _useLongData = value; } + } + + private IList _longData1; + public IList LongData1 + { + get { return _longData1; } + set { _longData1 = value; } + } + + private IList _longData2; + public IList LongData2 + { + get { return _longData2; } + set { _longData2 = value; } } private void Plotter_Resize(object sender, EventArgs e) @@ -457,7 +468,33 @@ namespace ProcessHacker.Components new Size(this.Width + 1, this.Height + 1); _managedBackBuffer = _graphicManager.Allocate(this.CreateGraphics(), this.ClientRectangle); + this.Draw(); } + + private void Plotter_MouseEnter(object sender, EventArgs e) + { + _showToolTip = true; + } + + private void Plotter_MouseLeave(object sender, EventArgs e) + { + _showToolTip = false; + toolTip.Hide(this); + } + + private void Plotter_MouseMove(object sender, MouseEventArgs e) + { + if (e.Location != _mouseLocation) + { + _mouseLocation = e.Location; + this.ShowToolTip(true); + } + else + { + _mouseLocation = e.Location; + this.ShowToolTip(); + } + } } } diff --git a/trunk/ProcessHacker/Components/Plotter.resx b/trunk/ProcessHacker/Components/Plotter.resx index ff31a6db5..a5979aadf 100644 --- a/trunk/ProcessHacker/Components/Plotter.resx +++ b/trunk/ProcessHacker/Components/Plotter.resx @@ -117,4 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + \ No newline at end of file diff --git a/trunk/ProcessHacker/Components/ProcessTree/ProcessNode.cs b/trunk/ProcessHacker/Components/ProcessTree/ProcessNode.cs index 12572306c..fe9ebc3b7 100644 --- a/trunk/ProcessHacker/Components/ProcessTree/ProcessNode.cs +++ b/trunk/ProcessHacker/Components/ProcessTree/ProcessNode.cs @@ -131,7 +131,7 @@ namespace ProcessHacker public int PPID { - get { if (_pitem.PID == _pitem.ParentPID) return -1; else return _pitem.ParentPID; } + get { if (_pitem.PID == _pitem.ParentPid) return -1; else return _pitem.ParentPid; } } public string PvtMemory @@ -178,10 +178,10 @@ namespace ProcessHacker { get { - if (_pitem.CPUUsage == 0) + if (_pitem.CpuUsage == 0) return ""; else - return _pitem.CPUUsage.ToString("F2"); + return _pitem.CpuUsage.ToString("F2"); } } diff --git a/trunk/ProcessHacker/Components/ProcessTree/ProcessTreeModel.cs b/trunk/ProcessHacker/Components/ProcessTree/ProcessTreeModel.cs index 32292aa10..f0bceac6e 100644 --- a/trunk/ProcessHacker/Components/ProcessTree/ProcessTreeModel.cs +++ b/trunk/ProcessHacker/Components/ProcessTree/ProcessTreeModel.cs @@ -43,8 +43,8 @@ namespace ProcessHacker ProcessNode itemNode = new ProcessNode(item); // find this process' parent - if (item.HasParent && _processes.ContainsKey(item.ParentPID)) - _processes[item.ParentPID].Children.Add(itemNode); + if (item.HasParent && _processes.ContainsKey(item.ParentPid)) + _processes[item.ParentPid].Children.Add(itemNode); else _roots.Add(itemNode); @@ -239,7 +239,7 @@ namespace ProcessHacker return ModifySort(n1.ProcessItem.Process.VirtualMemoryCounters.PageFaultCount.CompareTo( n2.ProcessItem.Process.VirtualMemoryCounters.PageFaultCount), sortO); else if (sortC == "cpu") - return ModifySort(n1.ProcessItem.CPUUsage.CompareTo(n2.ProcessItem.CPUUsage), sortO); + return ModifySort(n1.ProcessItem.CpuUsage.CompareTo(n2.ProcessItem.CpuUsage), sortO); else if (sortC == "username") return ModifySort(n1.Username.CompareTo(n2.Username), sortO); else if (sortC == "session id") diff --git a/trunk/ProcessHacker/DeltaManager.cs b/trunk/ProcessHacker/DeltaManager.cs index 4a66ebb71..82a5338a7 100644 --- a/trunk/ProcessHacker/DeltaManager.cs +++ b/trunk/ProcessHacker/DeltaManager.cs @@ -87,6 +87,12 @@ namespace ProcessHacker _subtractor = subtractor; } + public TValue this[TKey key] + { + get { return _deltas[key]; } + set { _deltas[key] = value; } + } + public TValue GetDelta(TKey key) { return _deltas[key]; diff --git a/trunk/ProcessHacker/Forms/HackerWindow.cs b/trunk/ProcessHacker/Forms/HackerWindow.cs index 5b8c20b7f..b3a81ddd6 100644 --- a/trunk/ProcessHacker/Forms/HackerWindow.cs +++ b/trunk/ProcessHacker/Forms/HackerWindow.cs @@ -264,16 +264,11 @@ namespace ProcessHacker private void sysInfoMenuItem_Click(object sender, EventArgs e) { - if (sysInfoThread == null) + if (sysInfoThread == null || !sysInfoThread.IsAlive) { SysInfoWindow = new SysInfoWindow(); sysInfoThread = new Thread(() => { - SysInfoWindow.Load += (sender_, e_) => - { - SysInfoWindow.Start(); - }; - Application.Run(SysInfoWindow); }); sysInfoThread.Start(); @@ -284,9 +279,6 @@ namespace ProcessHacker { SysInfoWindow.Show(); SysInfoWindow.Activate(); - - if (!SysInfoWindow.Started) - SysInfoWindow.Start(); })); } } @@ -476,7 +468,7 @@ namespace ProcessHacker for (int i = 0; i < processes.Count && processes.Count > Properties.Settings.Default.IconMenuProcessCount; i++) { - if (processes[i].CPUUsage == 0) + if (processes[i].CpuUsage == 0) { processes.RemoveAt(i); i--; @@ -488,7 +480,7 @@ namespace ProcessHacker } } - processes.Sort((i1, i2) => -i1.CPUUsage.CompareTo(i2.CPUUsage)); + processes.Sort((i1, i2) => -i1.CpuUsage.CompareTo(i2.CpuUsage)); if (processes.Count > Properties.Settings.Default.IconMenuProcessCount) { @@ -1279,7 +1271,7 @@ namespace ProcessHacker { this.BeginInvoke(new MethodInvoker(delegate { - cpuUsageIcon.Update(processP.CurrentCPUKernelUsage, processP.CurrentCPUUserUsage); + cpuUsageIcon.Update(processP.CurrentCpuKernelUsage, processP.CurrentCpuUserUsage); if (NotifyIcon.Icon != null) Win32.DestroyIcon(notifyIcon.Icon.Handle); @@ -1289,14 +1281,14 @@ namespace ProcessHacker UpdateStatusInfo(); notifyIcon.Text = "Process Hacker\n" + - "CPU Usage: " + (processP.CurrentCPUUsage * 100).ToString("F2") + "%"; + "CPU Usage: " + (processP.CurrentCpuUsage * 100).ToString("F2") + "%"; - if (processP.Dictionary.ContainsKey(processP.PIDWithMostCPUUsage)) - if (processP.Dictionary[processP.PIDWithMostCPUUsage].Name != null) + if (processP.Dictionary.ContainsKey(processP.PIDWithMostCpuUsage)) + if (processP.Dictionary[processP.PIDWithMostCpuUsage].Name != null) if (notifyIcon.Text.Length + - processP.Dictionary[processP.PIDWithMostCPUUsage].Name.Length + 7 < 62) - notifyIcon.Text += "\n" + processP.Dictionary[processP.PIDWithMostCPUUsage].Name + - ": " + processP.Dictionary[processP.PIDWithMostCPUUsage].CPUUsage.ToString("F2") + "%"; + processP.Dictionary[processP.PIDWithMostCpuUsage].Name.Length + 7 < 62) + notifyIcon.Text += "\n" + processP.Dictionary[processP.PIDWithMostCpuUsage].Name + + ": " + processP.Dictionary[processP.PIDWithMostCpuUsage].CpuUsage.ToString("F2") + "%"; })); } @@ -1309,7 +1301,7 @@ namespace ProcessHacker { try { - parent = processP.Dictionary[item.ParentPID]; + parent = processP.Dictionary[item.ParentPid]; parentText += " started by " + parent.Name + " (PID " + parent.PID.ToString() + ")"; } @@ -2070,7 +2062,7 @@ namespace ProcessHacker else statusGeneral.Text = "Loading..."; - statusCPU.Text = "CPU: " + (processP.CurrentCPUUsage * 100).ToString("N2") + "%"; + statusCPU.Text = "CPU: " + (processP.CurrentCpuUsage * 100).ToString("N2") + "%"; statusMemory.Text = "Phys. Memory: " + ((float)(processP.System.NumberOfPhysicalPages - processP.Performance.AvailablePages) * 100 / processP.System.NumberOfPhysicalPages).ToString("N2") + "%"; diff --git a/trunk/ProcessHacker/Forms/ProcessWindow.Designer.cs b/trunk/ProcessHacker/Forms/ProcessWindow.Designer.cs index 9b3bdbd6a..f26ab7083 100644 --- a/trunk/ProcessHacker/Forms/ProcessWindow.Designer.cs +++ b/trunk/ProcessHacker/Forms/ProcessWindow.Designer.cs @@ -41,7 +41,6 @@ this.tabControl = new System.Windows.Forms.TabControl(); this.tabGeneral = new System.Windows.Forms.TabPage(); this.groupProcess = new System.Windows.Forms.GroupBox(); - this.fileCurrentDirectory = new ProcessHacker.Components.FileNameBox(); this.label26 = new System.Windows.Forms.Label(); this.label7 = new System.Windows.Forms.Label(); this.textProtected = new System.Windows.Forms.TextBox(); @@ -61,7 +60,6 @@ this.textStartTime = new System.Windows.Forms.TextBox(); this.textCmdLine = new System.Windows.Forms.TextBox(); this.groupFile = new System.Windows.Forms.GroupBox(); - this.fileImage = new ProcessHacker.Components.FileNameBox(); this.pictureIcon = new System.Windows.Forms.PictureBox(); this.textFileDescription = new System.Windows.Forms.TextBox(); this.textFileCompany = new System.Windows.Forms.TextBox(); @@ -123,20 +121,14 @@ this.tabPerformance = new System.Windows.Forms.TabPage(); this.tablePerformance = new System.Windows.Forms.TableLayoutPanel(); this.groupCPUUsage = new System.Windows.Forms.GroupBox(); - this.plotterCPUUsage = new ProcessHacker.Components.Plotter(); this.groupBox3 = new System.Windows.Forms.GroupBox(); - this.plotterIO = new ProcessHacker.Components.Plotter(); this.groupBox2 = new System.Windows.Forms.GroupBox(); - this.plotterMemory = new ProcessHacker.Components.Plotter(); this.tabThreads = new System.Windows.Forms.TabPage(); - this.listThreads = new ProcessHacker.ThreadList(); this.tabToken = new System.Windows.Forms.TabPage(); this.tabModules = new System.Windows.Forms.TabPage(); - this.listModules = new ProcessHacker.ModuleList(); this.tabMemory = new System.Windows.Forms.TabPage(); this.label15 = new System.Windows.Forms.Label(); this.checkHideFreeRegions = new System.Windows.Forms.CheckBox(); - this.buttonSearch = new wyDay.Controls.SplitButton(); this.menuSearch = new System.Windows.Forms.ContextMenu(); this.newWindowSearchMenuItem = new System.Windows.Forms.MenuItem(); this.literalSearchMenuItem = new System.Windows.Forms.MenuItem(); @@ -144,18 +136,26 @@ this.stringScanMenuItem = new System.Windows.Forms.MenuItem(); this.heapScanMenuItem = new System.Windows.Forms.MenuItem(); this.structSearchMenuItem = new System.Windows.Forms.MenuItem(); - this.listMemory = new ProcessHacker.MemoryList(); this.tabEnvironment = new System.Windows.Forms.TabPage(); this.listEnvironment = new System.Windows.Forms.ListView(); this.columnVarName = new System.Windows.Forms.ColumnHeader(); this.columnVarValue = new System.Windows.Forms.ColumnHeader(); this.tabHandles = new System.Windows.Forms.TabPage(); this.checkHideHandlesNoName = new System.Windows.Forms.CheckBox(); - this.listHandles = new ProcessHacker.HandleList(); this.tabServices = new System.Windows.Forms.TabPage(); this.imageList = new System.Windows.Forms.ImageList(this.components); this.timerUpdate = new System.Windows.Forms.Timer(this.components); this.toolTip = new System.Windows.Forms.ToolTip(this.components); + this.fileCurrentDirectory = new ProcessHacker.Components.FileNameBox(); + this.fileImage = new ProcessHacker.Components.FileNameBox(); + this.plotterCPUUsage = new ProcessHacker.Components.Plotter(); + this.plotterIO = new ProcessHacker.Components.Plotter(); + this.plotterMemory = new ProcessHacker.Components.Plotter(); + this.listThreads = new ProcessHacker.ThreadList(); + this.listModules = new ProcessHacker.ModuleList(); + this.buttonSearch = new wyDay.Controls.SplitButton(); + this.listMemory = new ProcessHacker.MemoryList(); + this.listHandles = new ProcessHacker.HandleList(); this.vistaMenu = new wyDay.Controls.VistaMenu(this.components); this.tabControl.SuspendLayout(); this.tabGeneral.SuspendLayout(); @@ -276,16 +276,6 @@ this.groupProcess.TabStop = false; this.groupProcess.Text = "Process"; // - // fileCurrentDirectory - // - this.fileCurrentDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.fileCurrentDirectory.Location = new System.Drawing.Point(101, 73); - this.fileCurrentDirectory.Name = "fileCurrentDirectory"; - this.fileCurrentDirectory.ReadOnly = true; - this.fileCurrentDirectory.Size = new System.Drawing.Size(309, 24); - this.fileCurrentDirectory.TabIndex = 10; - // // label26 // this.label26.AutoSize = true; @@ -497,16 +487,6 @@ this.groupFile.TabStop = false; this.groupFile.Text = "File"; // - // fileImage - // - this.fileImage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.fileImage.Location = new System.Drawing.Point(103, 83); - this.fileImage.Name = "fileImage"; - this.fileImage.ReadOnly = true; - this.fileImage.Size = new System.Drawing.Size(309, 24); - this.fileImage.TabIndex = 10; - // // pictureIcon // this.pictureIcon.Location = new System.Drawing.Point(6, 19); @@ -594,7 +574,7 @@ this.flowStats.FlowDirection = System.Windows.Forms.FlowDirection.TopDown; this.flowStats.Location = new System.Drawing.Point(3, 3); this.flowStats.Name = "flowStats"; - this.flowStats.Size = new System.Drawing.Size(424, 345); + this.flowStats.Size = new System.Drawing.Size(424, 364); this.flowStats.TabIndex = 0; // // groupBox1 @@ -1208,29 +1188,6 @@ this.groupCPUUsage.TabStop = false; this.groupCPUUsage.Text = "CPU Usage (Kernel, User)"; // - // plotterCPUUsage - // - this.plotterCPUUsage.BackColor = System.Drawing.Color.Black; - this.plotterCPUUsage.Dock = System.Windows.Forms.DockStyle.Fill; - this.plotterCPUUsage.GridColor = System.Drawing.Color.Green; - this.plotterCPUUsage.GridSize = new System.Drawing.Size(12, 12); - this.plotterCPUUsage.IsMoved = true; - this.plotterCPUUsage.LineColor1 = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); - this.plotterCPUUsage.LineColor2 = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); - this.plotterCPUUsage.Location = new System.Drawing.Point(3, 16); - this.plotterCPUUsage.MoveStep = 3; - this.plotterCPUUsage.Name = "plotterCPUUsage"; - this.plotterCPUUsage.OverlaySecondLine = false; - this.plotterCPUUsage.ShowGrid = true; - this.plotterCPUUsage.Size = new System.Drawing.Size(412, 90); - this.plotterCPUUsage.TabIndex = 0; - this.plotterCPUUsage.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); - this.plotterCPUUsage.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); - this.plotterCPUUsage.TextMargin = new System.Windows.Forms.Padding(3); - this.plotterCPUUsage.TextPadding = new System.Windows.Forms.Padding(3); - this.plotterCPUUsage.TextPosition = System.Drawing.ContentAlignment.TopLeft; - this.plotterCPUUsage.UseSecondLine = true; - // // groupBox3 // this.groupBox3.Controls.Add(this.plotterIO); @@ -1242,29 +1199,6 @@ this.groupBox3.TabStop = false; this.groupBox3.Text = "I/O (R+O, W)"; // - // plotterIO - // - this.plotterIO.BackColor = System.Drawing.Color.Black; - this.plotterIO.Dock = System.Windows.Forms.DockStyle.Fill; - this.plotterIO.GridColor = System.Drawing.Color.Green; - this.plotterIO.GridSize = new System.Drawing.Size(12, 12); - this.plotterIO.IsMoved = true; - this.plotterIO.LineColor1 = System.Drawing.Color.Yellow; - this.plotterIO.LineColor2 = System.Drawing.Color.Purple; - this.plotterIO.Location = new System.Drawing.Point(3, 16); - this.plotterIO.MoveStep = 3; - this.plotterIO.Name = "plotterIO"; - this.plotterIO.OverlaySecondLine = true; - this.plotterIO.ShowGrid = true; - this.plotterIO.Size = new System.Drawing.Size(412, 90); - this.plotterIO.TabIndex = 0; - this.plotterIO.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); - this.plotterIO.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); - this.plotterIO.TextMargin = new System.Windows.Forms.Padding(3); - this.plotterIO.TextPadding = new System.Windows.Forms.Padding(3); - this.plotterIO.TextPosition = System.Drawing.ContentAlignment.TopLeft; - this.plotterIO.UseSecondLine = true; - // // groupBox2 // this.groupBox2.Controls.Add(this.plotterMemory); @@ -1276,29 +1210,6 @@ this.groupBox2.TabStop = false; this.groupBox2.Text = "Memory (Private Pages, Working Set)"; // - // plotterMemory - // - this.plotterMemory.BackColor = System.Drawing.Color.Black; - this.plotterMemory.Dock = System.Windows.Forms.DockStyle.Fill; - this.plotterMemory.GridColor = System.Drawing.Color.Green; - this.plotterMemory.GridSize = new System.Drawing.Size(12, 12); - this.plotterMemory.IsMoved = true; - this.plotterMemory.LineColor1 = System.Drawing.Color.Orange; - this.plotterMemory.LineColor2 = System.Drawing.Color.Cyan; - this.plotterMemory.Location = new System.Drawing.Point(3, 16); - this.plotterMemory.MoveStep = 3; - this.plotterMemory.Name = "plotterMemory"; - this.plotterMemory.OverlaySecondLine = true; - this.plotterMemory.ShowGrid = true; - this.plotterMemory.Size = new System.Drawing.Size(412, 90); - this.plotterMemory.TabIndex = 0; - this.plotterMemory.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); - this.plotterMemory.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); - this.plotterMemory.TextMargin = new System.Windows.Forms.Padding(3); - this.plotterMemory.TextPadding = new System.Windows.Forms.Padding(3); - this.plotterMemory.TextPosition = System.Drawing.ContentAlignment.TopLeft; - this.plotterMemory.UseSecondLine = true; - // // tabThreads // this.tabThreads.Controls.Add(this.listThreads); @@ -1310,17 +1221,6 @@ this.tabThreads.Text = "Threads"; this.tabThreads.UseVisualStyleBackColor = true; // - // listThreads - // - this.listThreads.Dock = System.Windows.Forms.DockStyle.Fill; - this.listThreads.DoubleBuffered = true; - this.listThreads.Highlight = false; - this.listThreads.Location = new System.Drawing.Point(0, 0); - this.listThreads.Name = "listThreads"; - this.listThreads.Provider = null; - this.listThreads.Size = new System.Drawing.Size(430, 351); - this.listThreads.TabIndex = 0; - // // tabToken // this.tabToken.ImageKey = "token"; @@ -1343,17 +1243,6 @@ this.tabModules.Text = "Modules"; this.tabModules.UseVisualStyleBackColor = true; // - // listModules - // - this.listModules.Dock = System.Windows.Forms.DockStyle.Fill; - this.listModules.DoubleBuffered = true; - this.listModules.Highlight = false; - this.listModules.Location = new System.Drawing.Point(0, 0); - this.listModules.Name = "listModules"; - this.listModules.Provider = null; - this.listModules.Size = new System.Drawing.Size(430, 351); - this.listModules.TabIndex = 0; - // // tabMemory // this.tabMemory.Controls.Add(this.label15); @@ -1392,18 +1281,6 @@ this.checkHideFreeRegions.UseVisualStyleBackColor = true; this.checkHideFreeRegions.CheckedChanged += new System.EventHandler(this.checkHideFreeRegions_CheckedChanged); // - // buttonSearch - // - this.buttonSearch.AutoSize = true; - this.buttonSearch.Location = new System.Drawing.Point(58, 6); - this.buttonSearch.Name = "buttonSearch"; - this.buttonSearch.Size = new System.Drawing.Size(99, 23); - this.buttonSearch.SplitMenu = this.menuSearch; - this.buttonSearch.TabIndex = 9; - this.buttonSearch.Text = "&String Scan..."; - this.buttonSearch.UseVisualStyleBackColor = true; - this.buttonSearch.Click += new System.EventHandler(this.buttonSearch_Click); - // // menuSearch // this.menuSearch.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { @@ -1450,19 +1327,6 @@ this.structSearchMenuItem.Text = "S&truct..."; this.structSearchMenuItem.Click += new System.EventHandler(this.structSearchMenuItem_Click); // - // listMemory - // - this.listMemory.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.listMemory.DoubleBuffered = true; - this.listMemory.Highlight = false; - this.listMemory.Location = new System.Drawing.Point(6, 59); - this.listMemory.Name = "listMemory"; - this.listMemory.Provider = null; - this.listMemory.Size = new System.Drawing.Size(418, 288); - this.listMemory.TabIndex = 0; - // // tabEnvironment // this.tabEnvironment.Controls.Add(this.listEnvironment); @@ -1527,19 +1391,6 @@ this.checkHideHandlesNoName.UseVisualStyleBackColor = true; this.checkHideHandlesNoName.CheckedChanged += new System.EventHandler(this.checkHideHandlesNoName_CheckedChanged); // - // listHandles - // - this.listHandles.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.listHandles.DoubleBuffered = true; - this.listHandles.Highlight = false; - this.listHandles.Location = new System.Drawing.Point(6, 30); - this.listHandles.Name = "listHandles"; - this.listHandles.Provider = null; - this.listHandles.Size = new System.Drawing.Size(418, 317); - this.listHandles.TabIndex = 0; - // // tabServices // this.tabServices.ImageKey = "cog"; @@ -1571,6 +1422,167 @@ this.timerUpdate.Interval = 2000; this.timerUpdate.Tick += new System.EventHandler(this.timerUpdate_Tick); // + // fileCurrentDirectory + // + this.fileCurrentDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.fileCurrentDirectory.Location = new System.Drawing.Point(101, 73); + this.fileCurrentDirectory.Name = "fileCurrentDirectory"; + this.fileCurrentDirectory.ReadOnly = true; + this.fileCurrentDirectory.Size = new System.Drawing.Size(309, 24); + this.fileCurrentDirectory.TabIndex = 10; + // + // fileImage + // + this.fileImage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.fileImage.Location = new System.Drawing.Point(103, 83); + this.fileImage.Name = "fileImage"; + this.fileImage.ReadOnly = true; + this.fileImage.Size = new System.Drawing.Size(309, 24); + this.fileImage.TabIndex = 10; + // + // plotterCPUUsage + // + this.plotterCPUUsage.BackColor = System.Drawing.Color.Black; + this.plotterCPUUsage.Data1 = null; + this.plotterCPUUsage.Data2 = null; + this.plotterCPUUsage.Dock = System.Windows.Forms.DockStyle.Fill; + this.plotterCPUUsage.GridColor = System.Drawing.Color.Green; + this.plotterCPUUsage.GridSize = new System.Drawing.Size(12, 12); + this.plotterCPUUsage.LineColor1 = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); + this.plotterCPUUsage.LineColor2 = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.plotterCPUUsage.Location = new System.Drawing.Point(3, 16); + this.plotterCPUUsage.LongData1 = null; + this.plotterCPUUsage.LongData2 = null; + this.plotterCPUUsage.MoveStep = 3; + this.plotterCPUUsage.Name = "plotterCPUUsage"; + this.plotterCPUUsage.OverlaySecondLine = false; + this.plotterCPUUsage.ShowGrid = true; + this.plotterCPUUsage.Size = new System.Drawing.Size(412, 90); + this.plotterCPUUsage.TabIndex = 0; + this.plotterCPUUsage.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.plotterCPUUsage.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); + this.plotterCPUUsage.TextMargin = new System.Windows.Forms.Padding(3); + this.plotterCPUUsage.TextPadding = new System.Windows.Forms.Padding(3); + this.plotterCPUUsage.TextPosition = System.Drawing.ContentAlignment.TopLeft; + this.plotterCPUUsage.UseLongData = false; + this.plotterCPUUsage.UseSecondLine = true; + // + // plotterIO + // + this.plotterIO.BackColor = System.Drawing.Color.Black; + this.plotterIO.Data1 = null; + this.plotterIO.Data2 = null; + this.plotterIO.Dock = System.Windows.Forms.DockStyle.Fill; + this.plotterIO.GridColor = System.Drawing.Color.Green; + this.plotterIO.GridSize = new System.Drawing.Size(12, 12); + this.plotterIO.LineColor1 = System.Drawing.Color.Yellow; + this.plotterIO.LineColor2 = System.Drawing.Color.Purple; + this.plotterIO.Location = new System.Drawing.Point(3, 16); + this.plotterIO.LongData1 = null; + this.plotterIO.LongData2 = null; + this.plotterIO.MoveStep = 3; + this.plotterIO.Name = "plotterIO"; + this.plotterIO.OverlaySecondLine = true; + this.plotterIO.ShowGrid = true; + this.plotterIO.Size = new System.Drawing.Size(412, 90); + this.plotterIO.TabIndex = 0; + this.plotterIO.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.plotterIO.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); + this.plotterIO.TextMargin = new System.Windows.Forms.Padding(3); + this.plotterIO.TextPadding = new System.Windows.Forms.Padding(3); + this.plotterIO.TextPosition = System.Drawing.ContentAlignment.TopLeft; + this.plotterIO.UseLongData = true; + this.plotterIO.UseSecondLine = true; + // + // plotterMemory + // + this.plotterMemory.BackColor = System.Drawing.Color.Black; + this.plotterMemory.Data1 = null; + this.plotterMemory.Data2 = null; + this.plotterMemory.Dock = System.Windows.Forms.DockStyle.Fill; + this.plotterMemory.GridColor = System.Drawing.Color.Green; + this.plotterMemory.GridSize = new System.Drawing.Size(12, 12); + this.plotterMemory.LineColor1 = System.Drawing.Color.Orange; + this.plotterMemory.LineColor2 = System.Drawing.Color.Cyan; + this.plotterMemory.Location = new System.Drawing.Point(3, 16); + this.plotterMemory.LongData1 = null; + this.plotterMemory.LongData2 = null; + this.plotterMemory.MoveStep = 3; + this.plotterMemory.Name = "plotterMemory"; + this.plotterMemory.OverlaySecondLine = true; + this.plotterMemory.ShowGrid = true; + this.plotterMemory.Size = new System.Drawing.Size(412, 90); + this.plotterMemory.TabIndex = 0; + this.plotterMemory.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.plotterMemory.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); + this.plotterMemory.TextMargin = new System.Windows.Forms.Padding(3); + this.plotterMemory.TextPadding = new System.Windows.Forms.Padding(3); + this.plotterMemory.TextPosition = System.Drawing.ContentAlignment.TopLeft; + this.plotterMemory.UseLongData = true; + this.plotterMemory.UseSecondLine = true; + // + // listThreads + // + this.listThreads.Dock = System.Windows.Forms.DockStyle.Fill; + this.listThreads.DoubleBuffered = true; + this.listThreads.Highlight = false; + this.listThreads.Location = new System.Drawing.Point(0, 0); + this.listThreads.Name = "listThreads"; + this.listThreads.Provider = null; + this.listThreads.Size = new System.Drawing.Size(430, 370); + this.listThreads.TabIndex = 0; + // + // listModules + // + this.listModules.Dock = System.Windows.Forms.DockStyle.Fill; + this.listModules.DoubleBuffered = true; + this.listModules.Highlight = false; + this.listModules.Location = new System.Drawing.Point(0, 0); + this.listModules.Name = "listModules"; + this.listModules.Provider = null; + this.listModules.Size = new System.Drawing.Size(430, 351); + this.listModules.TabIndex = 0; + // + // buttonSearch + // + this.buttonSearch.AutoSize = true; + this.buttonSearch.Location = new System.Drawing.Point(58, 6); + this.buttonSearch.Name = "buttonSearch"; + this.buttonSearch.Size = new System.Drawing.Size(99, 23); + this.buttonSearch.SplitMenu = this.menuSearch; + this.buttonSearch.TabIndex = 9; + this.buttonSearch.Text = "&String Scan..."; + this.buttonSearch.UseVisualStyleBackColor = true; + this.buttonSearch.Click += new System.EventHandler(this.buttonSearch_Click); + // + // listMemory + // + this.listMemory.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listMemory.DoubleBuffered = true; + this.listMemory.Highlight = false; + this.listMemory.Location = new System.Drawing.Point(6, 59); + this.listMemory.Name = "listMemory"; + this.listMemory.Provider = null; + this.listMemory.Size = new System.Drawing.Size(418, 288); + this.listMemory.TabIndex = 0; + // + // listHandles + // + this.listHandles.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listHandles.DoubleBuffered = true; + this.listHandles.Highlight = false; + this.listHandles.Location = new System.Drawing.Point(6, 30); + this.listHandles.Name = "listHandles"; + this.listHandles.Provider = null; + this.listHandles.Size = new System.Drawing.Size(418, 317); + this.listHandles.TabIndex = 0; + // // vistaMenu // this.vistaMenu.ContainerControl = this; diff --git a/trunk/ProcessHacker/Forms/ProcessWindow.cs b/trunk/ProcessHacker/Forms/ProcessWindow.cs index ffa1b8ca1..c629f686b 100644 --- a/trunk/ProcessHacker/Forms/ProcessWindow.cs +++ b/trunk/ProcessHacker/Forms/ProcessWindow.cs @@ -46,9 +46,6 @@ namespace ProcessHacker private TokenProperties _tokenProps; private ServiceProperties _serviceProps; - private DeltaManager _processStats = - new DeltaManager(new Int64Subtractor()); - private string _realCurrentDirectory; public ProcessWindow(ProcessItem process) @@ -80,29 +77,6 @@ namespace ProcessHacker this.Icon = Program.HackerWindow.Icon; Program.PWindows.Add(_pid, this); - - try - { - ProcessItem item = Program.HackerWindow.ProcessProvider.Dictionary[_pid]; - - _processStats.Add("System Other", - Program.HackerWindow.ProcessProvider.ProcessorPerf.IdleTime + - Program.HackerWindow.ProcessProvider.ProcessorPerf.DpcTime + - Program.HackerWindow.ProcessProvider.ProcessorPerf.InterruptTime); - _processStats.Add("System Kernel", - Program.HackerWindow.ProcessProvider.ProcessorPerf.KernelTime); - _processStats.Add("System User", - Program.HackerWindow.ProcessProvider.ProcessorPerf.UserTime); - _processStats.Add("Process Kernel", item.Process.KernelTime); - _processStats.Add("Process User", item.Process.UserTime); - _processStats.Add("IO Read+Other", - (long)item.Process.IoCounters.ReadTransferCount + - (long)item.Process.IoCounters.OtherTransferCount); - _processStats.Add("IO Write", - (long)item.Process.IoCounters.WriteTransferCount); - } - catch - { } } public MenuItem WindowMenuItem @@ -156,6 +130,23 @@ namespace ProcessHacker this.ClearStatistics(); + plotterCPUUsage.Data1 = _processItem.FloatHistoryManager[ProcessStats.CpuKernel]; + plotterCPUUsage.Data2 = _processItem.FloatHistoryManager[ProcessStats.CpuUser]; + plotterCPUUsage.GetToolTip = i => + ((plotterCPUUsage.Data1[i] + plotterCPUUsage.Data2[i]) * 100).ToString("N2") + + "% (K: " + (plotterCPUUsage.Data1[i] * 100).ToString("N2") + + "%, U: " + (plotterCPUUsage.Data2[i] * 100).ToString("N2") + ")"; + plotterMemory.LongData1 = _processItem.LongHistoryManager[ProcessStats.PrivateMemory]; + plotterMemory.LongData2 = _processItem.LongHistoryManager[ProcessStats.WorkingSet]; + plotterMemory.GetToolTip = i => + "Pvt. Memory: " + Misc.GetNiceSizeName(plotterMemory.LongData1[i]) + "\n" + + "Working Set: " + Misc.GetNiceSizeName(plotterMemory.LongData2[i]); + plotterIO.LongData1 = _processItem.LongHistoryManager[ProcessStats.IoReadOther]; + plotterIO.LongData2 = _processItem.LongHistoryManager[ProcessStats.IoWrite]; + plotterIO.GetToolTip = i => + "R+O: " + Misc.GetNiceSizeName(plotterIO.LongData1[i]) + "\n" + + "W: " + Misc.GetNiceSizeName(plotterIO.LongData2[i]); + try { _process = Process.GetProcessById(_pid); @@ -191,8 +182,6 @@ namespace ProcessHacker if (_pid == 0) textFileDescription.Text = "System Idle Process"; - this.UpdateDeltas(); - // add our handler to the process provider Program.HackerWindow.ProcessProvider.Updated += new ProcessSystemProvider.ProviderUpdateOnce(ProcessProvider_Updated); @@ -415,19 +404,19 @@ namespace ProcessHacker if (_processItem.HasParent) { - if (Program.HackerWindow.ProcessProvider.Dictionary.ContainsKey(_processItem.ParentPID)) + if (Program.HackerWindow.ProcessProvider.Dictionary.ContainsKey(_processItem.ParentPid)) { textParent.Text = - Program.HackerWindow.ProcessProvider.Dictionary[_processItem.ParentPID].Name + - " (" + _processItem.ParentPID.ToString() + ")"; + Program.HackerWindow.ProcessProvider.Dictionary[_processItem.ParentPid].Name + + " (" + _processItem.ParentPid.ToString() + ")"; } else { - textParent.Text = "Non-existent Process (" + _processItem.ParentPID.ToString() + ")"; + textParent.Text = "Non-existent Process (" + _processItem.ParentPid.ToString() + ")"; buttonInspectParent.Enabled = false; } } - else if (_processItem.ParentPID == -1) + else if (_processItem.ParentPid == -1) { // this process doesn't actually have a parent textParent.Text = "No Parent Process"; @@ -439,7 +428,7 @@ namespace ProcessHacker // another running process has the same PID as // its parent. We checked their creation times // back in ProcessSystemProvider.cs. - textParent.Text = "Non-existent Process (" + _processItem.ParentPID.ToString() + ")"; + textParent.Text = "Non-existent Process (" + _processItem.ParentPid.ToString() + ")"; buttonInspectParent.Enabled = false; } @@ -746,31 +735,10 @@ namespace ProcessHacker labelOtherUSERHandles.Text = ""; } - private void UpdateDeltas() - { - ProcessItem item = Program.HackerWindow.ProcessProvider.Dictionary[_pid]; - - // update deltas - _processStats.Update("System Other", - Program.HackerWindow.ProcessProvider.ProcessorPerf.IdleTime + - Program.HackerWindow.ProcessProvider.ProcessorPerf.DpcTime + - Program.HackerWindow.ProcessProvider.ProcessorPerf.InterruptTime); - _processStats.Update("System Kernel", - Program.HackerWindow.ProcessProvider.ProcessorPerf.KernelTime); - _processStats.Update("System User", - Program.HackerWindow.ProcessProvider.ProcessorPerf.UserTime); - _processStats.Update("Process Kernel", item.Process.KernelTime); - _processStats.Update("Process User", item.Process.UserTime); - _processStats.Update("IO Read+Other", - (long)item.Process.IoCounters.ReadTransferCount + - (long)item.Process.IoCounters.OtherTransferCount); - _processStats.Update("IO Write", - (long)item.Process.IoCounters.WriteTransferCount); - } - private void UpdatePerformance() - { - ProcessItem item = Program.HackerWindow.ProcessProvider.Dictionary[_pid]; + { + ProcessSystemProvider sysProvider = Program.HackerWindow.ProcessProvider; + ProcessItem item = sysProvider.Dictionary[_pid]; plotterCPUUsage.LineColor1 = Properties.Settings.Default.PlotterCPUKernelColor; plotterCPUUsage.LineColor2 = Properties.Settings.Default.PlotterCPUUserColor; @@ -780,24 +748,28 @@ namespace ProcessHacker plotterIO.LineColor2 = Properties.Settings.Default.PlotterIOWColor; // update graphs - long sysTotal = _processStats.GetDelta("System Kernel") + _processStats.GetDelta("System User") - + _processStats.GetDelta("System Other"); - float procKernel = (float)_processStats.GetDelta("Process Kernel") / sysTotal; - float procUser = (float)_processStats.GetDelta("Process User") / sysTotal; + long sysTotal = sysProvider.LongDeltas[SystemStats.CpuKernel] + sysProvider.LongDeltas[SystemStats.CpuUser] + + sysProvider.LongDeltas[SystemStats.CpuOther]; + float procKernel = (float)item.DeltaManager[ProcessStats.CpuKernel] / sysTotal; + float procUser = (float)item.DeltaManager[ProcessStats.CpuUser] / sysTotal; + long ioRO = item.DeltaManager[ProcessStats.IoRead] + item.DeltaManager[ProcessStats.IoOther]; + long ioW = item.DeltaManager[ProcessStats.IoWrite]; - plotterCPUUsage.Add(procKernel, procUser); plotterCPUUsage.Text = ((procKernel + procUser) * 100).ToString("F2") + "% (K: " + (procKernel * 100).ToString("F2") + "%, U: " + (procUser * 100).ToString("F2") + "%)"; - plotterMemory.Add(item.Process.VirtualMemoryCounters.PrivateBytes, - item.Process.VirtualMemoryCounters.WorkingSetSize); plotterMemory.Text = "Pvt: " + Misc.GetNiceSizeName(item.Process.VirtualMemoryCounters.PrivateBytes) + ", WS: " + Misc.GetNiceSizeName(item.Process.VirtualMemoryCounters.WorkingSetSize); - plotterIO.Add(_processStats.GetDelta("IO Read+Other"), _processStats.GetDelta("IO Write")); - plotterIO.Text = "R+O: " + Misc.GetNiceSizeName(_processStats.GetDelta("IO Read+Other")) + - ", W: " + Misc.GetNiceSizeName(_processStats.GetDelta("IO Write")); + plotterIO.Text = "R+O: " + Misc.GetNiceSizeName(ioRO) + ", W: " + Misc.GetNiceSizeName(ioW); + + plotterCPUUsage.MoveGrid(); + plotterCPUUsage.Draw(); + plotterMemory.MoveGrid(); + plotterMemory.Draw(); + plotterIO.MoveGrid(); + plotterIO.Draw(); // update statistics if (tabControl.SelectedTab == tabStatistics) @@ -977,7 +949,7 @@ namespace ProcessHacker try { ProcessWindow pForm = Program.GetProcessWindow( - Program.HackerWindow.ProcessProvider.Dictionary[_processItem.ParentPID], + Program.HackerWindow.ProcessProvider.Dictionary[_processItem.ParentPid], new Program.PWindowInvokeAction(delegate(ProcessWindow f) { f.Show(); @@ -1082,7 +1054,6 @@ namespace ProcessHacker { try { - this.UpdateDeltas(); this.UpdatePerformance(); } catch diff --git a/trunk/ProcessHacker/Forms/ProcessWindow.resx b/trunk/ProcessHacker/Forms/ProcessWindow.resx index d7336d631..c52c47535 100644 --- a/trunk/ProcessHacker/Forms/ProcessWindow.resx +++ b/trunk/ProcessHacker/Forms/ProcessWindow.resx @@ -133,206 +133,205 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 - ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABk + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABc LgAAAk1TRnQBSQFMAgEBCgEAAQwBAAEEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA AwABMAMAAQEBAAEgBgABMFYAAxUBHQMjATQDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AyQBNgMk - ATYDJAE2AyMBMwMVAR2EAAGHAQQBgAH/AYMBAAE+Af8BPwEAAT0B/wE8AQABPAH/ATkBAAE7Af8BxgIA - Af8BxgIAAf8BxAIAAf8BwAIAAf8BwAIAAf8BvwIAAf8BPAEPAQAB/wE6AQoBAAH/ATcBBgEAAf8BNQEC - AQAB/wEzAgAB/wQAAyMBNAPiAfUD9wH9A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D9wH9 - A98B8wMjATOEAAEBAQAB8wH/AZkBmwH+Af8BlgGYAf4B/wGTAZUB/gH/AZEBkwH+Af8ByQEDAQAB/wHg - AZMBHQH/Ad8BjwEZAf8B3wGNARUB/wHeAYoBEQH/AcACAAH/AaIByQGeAf8BnQHGAZkB/wGYAcMBlQH/ - AZQBwAGRAf8BAAEtAQAB/wMAAQEDJAE2A/kB/gP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/ - A/wB/wP8Af8D9wH9AyQBNoQAAQoBBwH1Af8BngGgAf4B/wEbAR4B/gH/ARYBGQH+Af8BlQGXAf4B/wHN - AQwBAAH/AeEBlwEjAf8B2gGAAQEB/wHZAT0BAAH/Ad8BjwEYAf8BxgIAAf8BqAHNAaQB/wE3AbABMQH/ - ATABqwEqAf8BmgHEAZYB/wEAATYBAAH/AwABAQMkATYD/AH/A/wB/wPdAf8D2wH/A9kB/wPXAf8D1QH/ - A9QB/wPUAf8D1AH/A/sB/wP8Af8DJAE2AwABAYAAARMBEQH2Af8BogGkAf4B/wEiASYB/gH/AR0BIQH+ - Af8BmQGbAf4B/wHPARUBAAH/AeMBnAEsAf8B3AGGAQoB/wHbAYMBBAH/AeABlAEeAf8BxgIAAf8BrwHR - AasB/wGAAbcBOgH/ATkBsgEzAf8BoAHIAZwB/wEAAYABAAH/AwABAQMkATYD/AH/A/wB/wP8Af8D/AH/ - A/sB/wP7Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP8Af8DJAE2AwABAYAAAhsB+AH/AagBqgH+Af8BKwEv - Af4B/wElASkB/gH/AZ4BoAH+Af8B0QEgAQAB/wHlAaIBNAH/Ad4BjAETAf8B3QGJAQ0B/wHiAZkBJgH/ - AckBBQEAAf8BtQHVAbAB/wGKAb0BgwH/AYMBuAE9Af8BpwHNAaMB/wEAAYsBBAH/AwABAQMkATYD/AH/ - A/wB/wPWAf8D0wH/A88B/wPNAf8DywH/A8gB/wPIAf8DxgH/A/gB/wP8Af8DJAE2AwABAYAAASMBJAH6 - Af8BrAGvAf4B/wEyATYB/gH/AS0BMQH+Af8BogGkAf4B/wHWASkBAAH/AecBpwE7Af8B4AGSARwB/wHf - AY8BFgH/AeQBngEuAf8BzQEOAQAB/wG6AdkBtQH/AbcB1gGxAf8BswHTAa4B/wGuAdEBqQH/AQUBlgEN - Af8DAAEBAyQBNgP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D+wH/A/kB/wP5Af8D+AH/A/wB/wMk - ATYDAAEBgAABKgEsAfwB/wGwAbMB/gH/ATkBPgH+Af8BNQE5Af4B/wGoAaoB/gH/AdgBNAEAAf8B6AGt - AYMB/wHiAZgBJQH/AeEBlQEgAf8B5QGjATYB/wHPARcBAAH/ASABvAEsAf8BHAG2AScB/wEXAbABIQH/ - ARIBqAEcAf8BDQGhARUB/wMAAQEDJAE2A/wB/wP8Af8DzgH/A8oB/wPGAf8DwwH/A8AB/wO9Af8DvAH/ - A7oB/wP2Af8D/AH/AyQBNgMAAQGAAAEwATMB/QH/AbQBtwH+Af8BgQGFAf4B/wE8AYEB/gH/AawBrwH+ - Af8B2QE7AQAB/wHqAbIBigH/AeQBnwEuAf8B4wGcASoB/wHnAagBPQH/AdEBIgEAAf8XAAEBAyQBNgP8 - Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP7Af8D+AH/A/YB/wPzAf8D8gH/A/wB/wMkATYDAAEBgAABNAE4 - Af4B/wG4AbsB/gH/AbYBuQH+Af8BswG2Af4B/wGwAbMB/gH/Ad8BhAEFAf8B7AG3AZIB/wHmAaUBOAH/ - AeYBogEzAf8B6QGtAYUB/wHWASsBAAH/FwABAQMkATYD/AH/A/wB/wPHAf8DwgH/A74B/wO4Af8DtAH/ - A7EB/wOuAf8DrAH/A+0B/wP8Af8DJAE2AwABAYAAATQBOAH+Af8BNAE4Af4B/wEyATYB/gH/AS4BMQH9 - Af8BKgEsAfwB/wHhAY0BEgH/Ae0BuwGZAf8B6QGsAYEB/wHnAagBPAH/AeoBswGNAf8B2AE0AQAB/xcA - AQEDJAE2A/wB/wP7Af8D/AH/A/wB/wP7Af8D+AH/A/UB/wPxAf8D7AH/A+oB/wPmAf8D/AH/AyQBNgMA - AQGUAAHiAZIBHAH/Ae4BwQGgAf8B6gGxAYkB/wHpAa4BhQH/Ae0BtwGUAf8B2wE8AQAB/xcAAQEDJAE2 - A/wB/wP5Af8DwAH/A7oB/wO0Af8DrwH/A6oB/wOlAf8D/AH/A/wB/wP8Af8D/AH/AyQBNgMAAQGUAAHm - AZsBJwH/AfABxQGmAf8B7AG2AZEB/wHrAbMBjAH/Ae4BvAGbAf8B3wGFAQcB/xcAAQEDJAE2A/wB/wP3 - Af8D+QH/A/cB/wP3Af8D8wH/A/AB/wPqAf8D/AH/A/YB/wP0Af8DVAGRAxcBIJgAAegBoAEwAf8B8gHI - AawB/wHwAcYBqAH/AfABxQGmAf8B7wHCAaIB/wHhAY4BEwH/GAADJAE2A/YB/QP0Af8D9QH/A/UB/wP1 - Af8D8QH/A+8B/wPpAf8D/AH/A+cB/wNUAZEDFwEgAwEBApgAAeoBpgE3Af8B6AGkATQB/wHoAaABLgH/ - AeYBnQErAf8B5AGZASUB/wHiAZUBHgH/GAADIwEzA9YB8AP2Af0D/AH/A/wB/wP8Af8D/AH/A/wB/wP8 - Af8D+AH/A1MBkQMXASADAQECzAADFAEcAyMBMwMkATYDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2 - AxcBIAMBAQKkAAMKAQ0BIgIhATEDIAEvAwUBBxgAAxEBFwGrAgAB/wFiAVkBSAH2AykBPzQAAwYBCAFA - Aj8BbgNWAbMBXgJYAd0BUgJdAfQBQAGEAaYB/QIAAbMB/wIAAagB/wJAAZwB/QJSAV0B9AFaAlgB3QNW - AbMBQAI/AW4DBgEIUAADGAEhA1ABnQFdAlQB8AOhAf8DqwH/A6cB/wOVAf8BZAJcAecDSgGKAxABFgwA - AboCAAH/AcABiQEAAf8BvwGJAQAB/wGvAgAB/wMqAUEwAAFbAlkBxAGHAbcB4AH/AZUBxgHmAf8BmwHN - AekB/wGcAc0B6QH/AZkBxwHnAf8BlQHBAeQB/wGOAbgB4AH/AYkBsAHdAf8BgQGnAdcB/wEAAZsBzwH/ - AQABjAHCAf8CAAGuAf8BWwJZAcQQAAMJAQwCRgFHAYECWQFcAckCAAHoAf8DHwEtKAADLwFKAWUCXQH0 - A84B/wPtAf8D9AH/A/UB/wP0Af8D7wH/A+IB/wO6Af8BZAJcAecDJAE1CAABwwGIAQAB/wHPAaIBAAH/ - Ac0BogGBAf8BwAGMAQAB/wGwAgAB/wFOAk0BlQMxAU4DJgE5AxYBHgMDAQQcAAFbAlkBxAGYAbkB1AH/ - AcUBxwHEAf8B7AHYAccB/wH2AesB4wH/AfoB9QHxAf8B8wHnAd4B/wHfAb8BpgH/AdABpAGBAf8BywGa - AQAB/wHIAZcBAAH/AaMBkwGMAf8CAAGcAf8BWwJZAcQMAAMtAUUCWgFgAd4BBgEEAesB/wEaARsB5wH/ - AgAB6QH/Ax8BLQFdAlkB0gFcAlkByQFHAkYBgQMJAQwYAAFcAlUB6gPeAf8D8wH/A9sB/wPSAf8D2wH/ - A9YB/wPAAf8DyQH/A+YB/wPEAf8BXAJVAeoIAANAAXEBzAGZAQAB/wHQAaMBgQH/Ac8BpAGDAf8BygGe - AQAB/wG8AYUBAAH/Aa8CAAH/AacCAAH/AZ4CAAH/AVsCWAHGAwcBCRgAAx0BKgHmAcMBpQH/Ae8B1gHA - Af8B+wHyAeoB/wH+AfwB+gL/Af4B/QH/Af4B/QH8Af8B/AH2AfAB/wH4AegB2QH/AfYB4wHRAf8B9gHi - Ac4B/wHmAcgBrQH/Ac4BoAEAAf8DHQEqCAADNAFUAhAB8wH/ASsBLQHuAf8BlAGZAesB/wGNAZEB6QH/ - AgAB7AH/Ax8BLQFdAlkB0gHWAY4BEAH/AbgBFAEAAf8BYAJaAd4DLgFIFAABXAJVAeoD8AH/A94B/wPU - Af8D0gH/A9sB/wPWAf8DvwH/A7AB/wOzAf8D3gH/AVwCVQHqDAADQQFyAc4BnQEAAf8B1QGsAYwB/wHL - AZsBAAH/AcwBoAEAAf8ByAGbAQAB/wHFAZUBAAH/AcABjwEAAf8BrAIAAf8DQgF2HAABWAJWAbkB7QHT - AbsB/wH6AfAB5QH/Af0B+QH1Af8B/gH8AfoB/wH+Af0B/AH/Af0B+QH0Af8B9gHjAc8B/wH3AeUB0wH/ - AfYB4wHRAf8B3QG5AZoB/wFXAlYBuAgAAxABFQNfAfMBlQGZAfIB/wGlAaoB7gH/ASkBgQHmAf8BlwGa - AesB/wIAAe8B/wMfAS0BXQFbAVkB0gHbAZkBHgH/AeYBpAEtAf8BywGAAQUB/wGmAQMBAAH/AzQBVBAA - AVwCVQHqA/IB/wPiAf8D2AH/A9UB/wPcAf8D2AH/A8AB/wOzAf8DtwH/A+AB/wFcAlUB6hAAAVYCVQGx - AdMBqAGGAf8B1gGsAY4B/wHJAZgBAAH/AcQBkAEAAf8BvwGKAQAB/wHCAY8BAAH/Ab8BiwEAAf8BXwFd - AUYB+wMdASkcAAFVAlMBsAN/Af4B9wHqAd4B/wH+AfoB9wH/Af4B/AH5Af8B/QH3AfIB/wH6Ae0B4gH/ - AesB0AG3Af8CfwF+Af4DVAGuDAADDQERA04BmQJiAWoB+QGEAYUB9AH/AaMBqAHvAf8BoAGlAe0B/wIA - AfEB/wMfAS0CXQFZAdIB3gGhAScB/wHeAYkBCQH/AeYBpgEtAf8B0AGHAQoB/wFfAkwB8wMQARUMAAFc - AlUB6gPzAf8D5wH/A90B/wPZAf8D4AH/A9sB/wPEAf8DuAH/A7sB/wPhAf8BXAJVAeoQAAMxAU4B1AGj - AQAB/wHcAbUBmAH/AdABoQEAAf8BzAGaAQAB/wHPAaQBgwH/AcgBmgEAAf8BAAGMAQAB/wEAAbgBAAH/ - AV8BTgEwAfsDVAGvAwcBCRgAAycBOgFhAlsB4QHzAeIB0gH/AfwB9AHtAf8B+wHxAecB/wHpAcwBtQH/ - AWECXAHcAyYBOBAAA0IBcwM8AWYDFAEbA0oBjQJdAV8B8wEqASwB8wH/AQcBBgH0Af8DHwEtAl0BWQHS - AeEBqAGBAf8B4AGSARIB/wHZAScBAAH/AecBqAGEAf8BvgEeAQAB/wNIAYQMAAFcAlUB6gP0Af8D6gH/ - A+EB/wPdAf8D4wH/A94B/wPJAf8DvQH/A78B/wPiAf8BXAJVAeoQAAMmATkB2wGrAYkB/wHhAb0BogH/ - AdYBqgGHAf8B2QGzAZQB/wHOAZ8BAAH/AV8CXQH7AQABvAEAAf8BkwIAAf8BsAIAAf8BpAIAAf8BYQJe - AdoDAwEEHAADWQHHAfQB4wHQAf8B8wHfAc0B/wFbAlkBwxgAAVkBXAFZAc8BkAG/AZMB/wFVAVwBVQHq - A0EBcgMVAR0DRAF7A10B7QMfAS0CXQFZAdIB5AGwAYsB/wHjAZwBGwH/Ad0BhQECAf8B4gGWARUB/wHa - AZcBGwH/AVwCWQHPDAABXAJVAeoD9QH/A+4B/wPmAf8D4gH/A+YB/wPhAf8DzQH/A8IB/wPCAf8D4wH/ - AVwCVQHqEAADFgEeAeABsQGPAf8B5gHEAasB/wHiAb8BpAH/AdgBrQGOAf8DTQH6A0MBdwMrAfwBuwGE - AQAB/wHAAY8BAAH/AbwBigEAAf8BnAIAAf8DFgEeHAABWwJZAcMB9AHhAc4B/wHzAd8BzAH/AVkCVwHC - GAABWgJdAfABygHoAcgB/wGvAdkBqwH/AZIBvwGUAf8DXQHtAUUBRgFFAX4DDwEUAxIBGAJdAVkB0gHn - AbcBkwH/AecBpgElAf8B4AGQAQsB/wHeAY4BCgH/AeYBrQGIAf8BXwFUAUwB8wwAAVwCVQHqA/YB/wPr - Af8D3gH/A9YB/wPVAf8D0QH/A8MB/wO8Af8DwAH/A+UB/wFcAlUB6hAAAwMBBAFhAl4B2gHkAbsBnwH/ - AeQBuwGfAf8DKwH8AQABwQEAAf8DKwH8AccBlgEAAf8BywGeAQAB/wG8AYUBAAH/AcMBkgEAAf8BpgIA - Af8DJgE5FAADJgE4AV4CWAHdAfMB3QHJAf8B+gHuAeIB/wH5AesB3gH/Ae0B0AG2Af8BXwJaAdsDJgE4 - EAABYAJqAfkBtgHgAbEB/wEpAcwBHQH/AZIB0gGJAf8BrQHZAakB/wGJAbgBiwH/A1ABnQM1AVYCYgFJ - AfYB7wHIAakB/wHmAaYBIQH/AeIBmwEVAf8B4gGYARQB/wHnAbMBjwH/AV0BXAFOAfAMAAFcAlUB6gP3 - Af8D5wH/A+8B/wP2Af8D+wH/A/oB/wPwAf8D3gH/A8MB/wPmAf8BXAJVAeoUAAMHAQkDVAGvAWoCZgH5 - AQABxQGCAf8BtQGwAYEB/wHYAbABkgH/AdcBrgGPAf8ByQGXAQAB/wHDAY8BAAH/AcgBmwEAAf8BsQIA - Af8DMQFOEAADVAGvA38B/gH5AewB4AH/Af0B+AH0Af8B+wHwAeYB/wH4AecB1wH/AfkB6wHeAf8B8gHa - AcUB/wN/Af4DVAGuDAADXAHPAboB3wG4Af8BKAHMARsB/wEUAcYBBwH/ASAByAEUAf8BqAHaAaMB/wEW - AagBGwH/AygBPANbAcMB5gG1AY4B/wHwAcwBrAH/AeUBpgEfAf8B6QGxAYQB/wHjAa8BiAH/AlwBWQHP - DAABXAJVAeoD+AH/A/4Z/wP7Af8D6gH/AVwCVQHqHAADGwEmAagBpgGEAf0B4gG+AaMB/wHfAbcBmgH/ - AdUBqAGGAf8B0AGhAQAB/wHLAZoBAAH/Ac4BogGBAf8BvwGLAQAB/wFOAk0BlQwAAVcCVgG4AfkB4wHN - Af8B+wHzAewB/wH+AfoB9wH/Af4B+wH4Af8B/AH1Ae0B/wH3AeYB1QH/AfYB4QHMAf8B+QHsAd8B/wH5 - AesB3QH/AesBzgG0Af8BVwJWAbgIAANIAYQBswHaAbUB/wGiAdgBmgH/ARsBygENAf8BFAHGAQYB/wGA - AcwBIwH/AaMBzgGjAf8BWQFcAVkBzwMiATIBRwIrAfwB8gHRAbIB/wHrAbkBjQH/AfAByQGqAf8B2AGc - AR4B/wNIAYQMAAFZAlcBvwPhAf8D/hn/A/sB/wPPAf8BUgJRAaEgAANCAXYB5AG6AZ0B/wHmAcQBqwH/ - AeIBvgGkAf8B3gG5AZwB/wHZAbIBkwH/AdEBowEAAf8B0QGmAYUB/wG7AgAB/wMpAT8EAAMdASoBwAHF - Ac0B/wGaAbcB3AH/AQABpgHVAf8BAAGVAcoB/wEAAYcBvgH/AgABswH/AgABqAH/AgABnwH/AgABmAH/ - AgABmgH/AQABgwGnAf8BiAGUAZoB/wMdASoEAAMNARIDXwHzAb4B4QG+Af8BlAHUAYkB/wEcAcoBEAH/ - ARwByQEOAf8BngHWAZcB/wGTAcEBlgH/Az0BaQNOAZYB5wG0AY4B/wHzAdMBtQH/AekBuwGYAf8CXwFM - AfMDDQESDAADHQEqAVwCWAHRA9AB/wPoAf8D8wH/A/0B/wP8Af8D7QH/A+AB/wPCAf8BWwJZAcMDFAEb - IAADBwEJAVsCWAHGAeMBtAGTAf8B3wGxAY4B/wHaAasBiQH/AdoBrQGMAf8B3AG1AZgB/wHXAa8BkAH/ - AcwBmwEAAf8DTQH6BAABXAJYAdEBhwG3AeAB/wGVAcYB5gH/AZsBzQHpAf8BnAHNAekB/wGZAccB5wH/ - AZUBwQHkAf8BjgG4AeAB/wGJAbAB3QH/AYEBpwHXAf8BAAGbAc8B/wEAAYwBwgH/AgABrgH/AVwCWAHR - CAADMgFRAaAB1QGoAf8BugHgAbsB/wGnAdoBoAH/ASsBzgEeAf8BLQHNASEB/wGwAdkBrQH/A10B7QMZ - ASMDXQHtAesBwgGeAf8B3QGiASEB/wMyAVEUAAMFAQcBNQI0AVUDVAGuAWACWwHWAV8CXQH7AWoCZgH5 - AVwCWgHNA1IBqQMtAUYDAgEDKAADAwEEAxYBHgMmATkDMQROAZQB2AGnAYIB/wHXAawBiwH/AdMBpwGE - Af8BYgFcAUkB9gQAAVsCWQHEAYcBtwHgAf8BlQHGAeYB/wGdAc8B6gH/AaEB0wHsAf8BoAHRAesB/wGb - AcoB6AH/AZYBwgHlAf8BjwG6AeIB/wGHAbEB3QH/AQABowHUAf8BAAGQAcQB/wIAAa4B/wFbAlkBxAwA - AykBPwNgAd4BtAHcAbcB/wG8AeABugH/AbkB4QG1Af8BzgHqAcsB/wGkAc4BpgH/AU0CTgGWAz0BaQNg - Ad4DKQE/fAADKQE+AV8CXQH7AWICXAH2Ay4BSAQAAwYBCAFAAj8BbgNWAbMBXgJYAd0BZQJdAfQBQAGd - AaYB/QEAAZkB0QH/AQABkAHIAf8BQAGEAaYB/QFSAl0B9AFaAlgB3QNWAbMBQAI/AW4DBgEIEAADCQEM - A0YBfgNbAcYBKwE8ASsB/AErATkBKwH8A1sBxgNFAX0DAgEDAwcBChEAAZ0B2QH/AQABmQHYAf8BAAGU - AdcB/wEAAZAB1gH/AQABjAHVAf8BAAGIAdQB/wEAAYQB0wH/AQABgQHSAf8CAAHRAf8CAAHRAf8CAAHQ - Af8CAAHPAf8CAAHPAf8CAAHOAf9gAAM7AWMBWQJXAb8BWAJXAb8DOwFjIAADFQEdAyMBNAMkATYDJAE2 - AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDIwEzAxUBHQEAAaMB2gH/AbwB6wH6Af8BvAHr - AfwB/wG/Ae4B/gH/AcYB9AL/Ac4B+AL/AdMB+gL/AdAB+AL/AccB8gL/AboB6QH8Af8BswHkAfkB/wGw - AeIB+AH/AbAB4gH4Af8CAAHPAf9UAAMdASkDCgEOAwEBAgFcAlUB6gO9Af8DsgH/AVwCVQHqAwEBAgMK - AQ4DHQEpFAADIwE0A1kB9QGoAqYB/QP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/AagCpgH9 - AV8CXQHzAyMBMwEAAagB2wH/Ab8B7AH7Af8BAAHPAfUB/wEAAbAB7AH/AwAB/wIAAYkB/wEAAYkBvgH/ - AQABmgHIAf8BAAGuAecB/wEAAaUB5gH/AQABmgHhAf8BAAG4Ae4B/wGxAeMB+AH/AgAB0AH/CAADUgGp - AcMBjgEAAf8BwAGLAQAB/wG+AYgBAAH/AbsBhQEAAf8BuQGDAQAB/wG0AgAB/wGyAgAB/wGxAgAB/wGu - AgAB/wGtAgAB/wGrAgAB/wGpAgAB/wGpAgAB/wNSAakMAAFQAk8BmwNAAf0BZAJcAecDEgEZAWQCXAHn - A8sB/wPHAf8BYwJcAecDEgEZA1wB5wNAAf0BUAJPAZsIAAM3AVsBXQFUAU4B8AFiAVwBSAH2AeUBtwGa - Af8B+wL6Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8BqAKmAf0DJAE2AQABrQHc - Af8BwQHuAfsB/wEAAdMB9wH/AQAB2wH8Af8CAAGFAf8BlAHHAfkB/wGRAckB+QH/AQABhQHJAf8CAAGu - Af8BAAG9AewB/wEAAb4B7wH/AQABugHuAf8BswHjAfkB/wIAAdEB/wgAAcgBkgEANf8BqQIAAf8IAANE - AXsDvAH/A94B/wOmAf8BZQJdAfQDfwH+A8QB/wPCAf8BbgJtAf4BZQJdAfQDpgH/A9IB/wOBAf8DRAF7 - BAABYgJYAe8B5gG4AZwB/wHpAb8BpQH/AdwBmwEAAf8B5QG4AZ0B/wP8Af8D/AH/A/wB/wP7Af8D+wH/ - A/sB/wP7Af8D+wH/A/sB/wP8Af8DJAE2AQABsgHdAf8BwwHvAfsB/wEAAdYB+AH/AQABtgHsAf8BAAGJ - AaoB/wHgAfIC/wEAAZoB2AH/AgABvgH/AQABmAHFAf8BAAGGAcUB/wEAAZsB3gH/AQABvgHvAf8BtAHl - AfkB/wIAAdIB/wgAAcoBlAEAC/8B/gP/Af0B/wL+Af0B/wL+AfwB/wL+AfwB/wL+AfwB/wL+AfwB/wL+ - AfoB/wL+AfoB/wL8AfkF/wGqAgAB/wgAA0UBfQN/Af4D1QH/A8UB/wPLAf8D0QH/A8kB/wPHAf8DzAH/ - A8UB/wO9Af8DywH/AW8CbgH+A0UBfQQAAW0CZwH3AesBxAGtAf8B7AHIAbIB/wHqAcEBqQH/Ad4BngEA - Af8B5wG7AaEB/wP8Af8D+wH/A/sB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/wB/wMkATYBAAG3Ad4B/wHG - AfAB/AH/AQAB2QH4Af8BAAHiAf0B/wEAAbcB2QH/AQABtgHVAf8BkAG3AdEB/wEAAckB5AH/AQAB3wH1 - Af8BAAHQAe0B/wEAAZgB3AH/AQABugHtAf8BtgHnAfkB/wEAAYMB0wH/CAABzAGXAQAH/wH8A/8B/QH/ - Av4B/AH/Av4B/AH/Av4B+wH/Av0B+gH/Av0B+gH/Av0B+gH/Av0B+gH/AvwB9wH/AvsB9gX/AawCAAH/ - DAADSAGFA8UB/wPBAf8DxQH/A8cB/wOqAf8DpwH/A8EB/wO+Af8DtQH/A6oB/wNIAYUIAANCAXUBagJm - AfkB7AHHAbAB/wHtAcoBtQH/AesBwwGrAf8B3gGhAQAB/wHnAboBnwH/A/sB/wP7Af8D+wH/A/oB/wP6 - Af8D+AH/A/gB/wP8Af8DJAE2AQABuwHfAf8BxwHxAfwB/wEAAdwB+QH/AQABuwHtAf8BAAG9Ae8B/wEA - AcYB5wH/AQABuAHWAf8BwgH2Af0B/wEAAd8B9wH/AQAB4gH4Af8BAAHTAfAB/wEAAZcB3AH/AagB3AH1 - Af8BAAGIAdQB/wgAAdEBnAEABf8C/gH8Af8C/gH8Af8C/gH8Af8C/QH7Af8C/QH7Af8C/QH6Af8C/QH4 - Af8C+wH5Af8B+wH6AfcB/wH7AfoB9gH/AfsB+AH0Bf8BsAIAAf8EAAFcAloBzQFfAlgB4wFhAlYB7gPP - Af8DxgH/A8wB/wFbAlgBxgMsAUQDLAFEAVsCWAHGA8EB/wO8Af8DuQH/AWECVgHuAVsCWAHjA1oBzQQA - A0MBeAN/Af4B7QHIAbMB/wHtAc0BuAH/AekBvgGjAf8B1gGOAQAB/wP8Af8D/AH/A/wB/wP7Af8D+QH/ - A/kB/wP4Af8D/AH/AyQBNgEAAb8B4AH/AcgB8wH8Af8BAAHfAfkB/wGJAeYB/QH/AZUB5wL/AZoB5QL/ - AQABygHnAf8BAAHLAecB/wHHAfcB/QH/AQAB3AH1Af8BAAHhAfcB/wEAAdQB8QH/AQABmQHeAf8BAAGN - AdYB/wgAAdQBngEABf8C/gH8Af8C/QH7Af8C/QH8Af8C/QH7Af8C/QH5Af8C/AH4Af8B+wH5AfcB/wH7 - AfkB9QH/AfsB+AH0Af8B+wH3AfIB/wH7AfUB8gX/AbICAAH/BAABqAKmAf0D4gH/A9IB/wPGAf8DzQH/ - A7EB/wMsAUQIAAMsAUQDqAH/A8IB/wO3Af8DwAH/A9IB/wNAAf0HAAEBA0wBkgHgAakBiAH/AesBxwGw - Af8B3QGhAQAB/wG8AaUBlQH/A6wB/wPQAf8D1AH/A+8B/wP5Af8D9gH/A/YB/wP8Af8DJAE2AQABwgHh - Af8ByQHzAfwB/wHLAfMB/QH/AdQB9gH+Af8B1wH2Av8B2AH0Av8B4AH4Av8BqQHjAfUB/wEAAdMB7gH/ - AccB9wH9Af8BAAHcAfUB/wEAAeIB9wH/AQAB1gHyAf8BAAGYAd4B/wMhATAEAAHVAaABAAX/Av0B/AH/ - Av0B+wH/Av0B+gH/AvwB+QH/AfwB+wH3Af8B+wH5AfUB/wH7AfgB9AH/AfsB9wHzAf8B+wH1AfIB/wH6 - AfMB7wH/AfgB8gHsBf8BtQIAAf8EAAGoAqYB/QPpAf8D1gH/A8kB/wPOAf8DpQH/AywBRAgAAywBRAOs - Af8DxAH/A7oB/wPGAf8D3QH/A0AB/QcAAQEDJAE2AfAB1gHGAf8B3gGtAZAB/wHEAa8BowH/A9UB/wO7 - Af8DpgH/A6AB/wOQAf8DyQH/A/MB/wPyAf8D/AH/AyQBNgEAAcMB4QH/AYgBoAGoAf8DkQH/A44B/wEA - AbkB3AH/AQABuAHfAf8BAAG1Ad4B/wEAAbEB3QH/AQABsAHeAf8BAAHUAe4B/wHEAfYB/QH/AQAB3QH2 - Af8BAAHKAe0B/wEAAaMB1wH/AWACWQHsAxsBJgHYAaIBAAX/Av0B+gH/AvwB+gH/AfwB+wH5Af8B+wH6 - AfYB/wH7AfgB9QH/AfsB9wH0Af8B+wH2AfEB/wH4AfQB7gH/AfcB8gHrAf8B9wHwAeoB/wH2AewB6AX/ - AbcBgQEAAf8EAAFcAloBzQFfAlgB4wFhAlYB7gPYAf8DzQH/A7wB/wFbAlgBxgMsAUQDLAFEAVsCWAHG - A8MB/wPCAf8DzQH/AWECVgHuAV8CWAHjAVwCWgHNBwABAQMkATYD/AH/A/sB/wOsAf8DywH/A9IB/wPJ - Af8D0gH/A8YB/wOPAf8D7wH/A+0B/wP8Af8DJAE2BAABWwJZAcMDxgH/A5QB/wMGAQgQAAM3AVoBAAHT - AesB/wGyAeMB+QH/AYsBwAHnAf8BrgHTAfYB/wHEAeAB/AH/A2cB9wHZAaMBAAX/AfwB+wH5Af8B/AH7 - AfgB/wH7AfkB9wH/AfsB9wH0Af8B+gH3AfIB/wH5AfUB8AH/AfcB8wHtAf8B9gHvAeoB/wH1AesB5wH/ - AfMB6gHkAf8B8gHnAd4F/wG6AYUBAAH/DAADSAGFA9QB/wPMAf8DyQH/A7oB/wOcAf8DoQH/A8IB/wPG - Af8DwQH/A7cB/wNIAYUPAAEBAyQBNgP8Af8D+wH/A9sB/wOyAf8D1gH/A6AB/wOSAf8DwAH/A4oB/wPq - Af8D5gH/A/wB/wMkATYEAANUAa4DxAH/A6EB/wMdASkQAAMdASkBAAGZAakB/wEAAb4B5wH/AbQB0gHw - Af8B5QHzAv8BrAHSAe8B/wFfAlcB6AHbAaQBADX/Ab0BhwEAAf8IAANFAX0DfwH+A9wB/wPUAf8D2QH/ - A9sB/wPWAf8D1AH/A9kB/wPSAf8DywH/A8gB/wF6AnkB/gNFAX0LAAEBAyQBNgP8Af8D+QH/A9oB/wO1 - Af8D5gH/A5oB/wOwAf8DrwH/A70B/wP8Af8D/AH/A/wB/wMkATYEAANCAXUDugH/A78B/wFeAlgB3QMW - AR8DBAEFAwQBBQMWAR8BZQJeAeUDqAH/AQABpAGzAf8BAAGlAdgB/wGFAbEB2wH/AQABnQHQAf8DOAFe + ATYDJAE2AyMBMwMVAR2EAAGHAQIBgAH/AYMBAAE8Af8BPQEAATsB/wE6AQABOgH/ATcBAAE5Af8BxgIA + Af8BxgIAAf8BxAIAAf8BwAIAAf8BwAIAAf8BvwIAAf8BOgENAQAB/wE4AQgBAAH/ATUBBAEAAf8BMwIA + Af8BMQIAAf8EAAMjATQDzgH1A/EB/QP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/EB/QPJ + AfMDIwEzhgAB8wH/AZkBmwH+Af8BlgGYAf4B/wGTAZUB/gH/AZEBkwH+Af8ByQEBAQAB/wHgAZMBGwH/ + Ad8BjwEXAf8B3wGNARMB/wHeAYoBDwH/AcACAAH/AaIByQGeAf8BnQHGAZkB/wGYAcMBlQH/AZQBwAGR + Af8BAAErAQAB/wMAAQEDJAE2A/UB/gP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8 + Af8D8QH9AyQBNoQAAQgBBQH1Af8BngGgAf4B/wEZARwB/gH/ARQBFwH+Af8BlQGXAf4B/wHNAQoBAAH/ + AeEBlwEhAf8B2gGAAQAB/wHZATsBAAH/Ad8BjwEWAf8BxgIAAf8BqAHNAaQB/wE1AbABLwH/AS4BqwEo + Af8BmgHEAZYB/wEAATQBAAH/AwABAQMkATYD/AH/A/wB/wPdAf8D2wH/A9kB/wPXAf8D1QH/A9QB/wPU + Af8D1AH/A/sB/wP8Af8DJAE2AwABAYAAAREBDwH2Af8BogGkAf4B/wEgASQB/gH/ARsBHwH+Af8BmQGb + Af4B/wHPARMBAAH/AeMBnAEqAf8B3AGGAQgB/wHbAYMBAgH/AeABlAEcAf8BxgIAAf8BrwHRAasB/wGA + AbcBOAH/ATcBsgExAf8BoAHIAZwB/wEAAYABAAH/AwABAQMkATYD/AH/A/wB/wP8Af8D/AH/A/sB/wP7 + Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP8Af8DJAE2AwABAYAAAhkB+AH/AagBqgH+Af8BKQEtAf4B/wEj + AScB/gH/AZ4BoAH+Af8B0QEeAQAB/wHlAaIBMgH/Ad4BjAERAf8B3QGJAQsB/wHiAZkBJAH/AckBAwEA + Af8BtQHVAbAB/wGKAb0BgwH/AYMBuAE7Af8BpwHNAaMB/wEAAYsBAgH/AwABAQMkATYD/AH/A/wB/wPW + Af8D0wH/A88B/wPNAf8DywH/A8gB/wPIAf8DxgH/A/gB/wP8Af8DJAE2AwABAYAAASEBIgH6Af8BrAGv + Af4B/wEwATQB/gH/ASsBLwH+Af8BogGkAf4B/wHWAScBAAH/AecBpwE5Af8B4AGSARoB/wHfAY8BFAH/ + AeQBngEsAf8BzQEMAQAB/wG6AdkBtQH/AbcB1gGxAf8BswHTAa4B/wGuAdEBqQH/AQMBlgELAf8DAAEB + AyQBNgP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D+wH/A/kB/wP5Af8D+AH/A/wB/wMkATYDAAEB + gAABKAEqAfwB/wGwAbMB/gH/ATcBPAH+Af8BMwE3Af4B/wGoAaoB/gH/AdgBMgEAAf8B6AGtAYMB/wHi + AZgBIwH/AeEBlQEeAf8B5QGjATQB/wHPARUBAAH/AR4BvAEqAf8BGgG2ASUB/wEVAbABHwH/ARABqAEa + Af8BCwGhARMB/wMAAQEDJAE2A/wB/wP8Af8DzgH/A8oB/wPGAf8DwwH/A8AB/wO9Af8DvAH/A7oB/wP2 + Af8D/AH/AyQBNgMAAQGAAAEuATEB/QH/AbQBtwH+Af8BgQGFAf4B/wE6AYEB/gH/AawBrwH+Af8B2QE5 + AQAB/wHqAbIBigH/AeQBnwEsAf8B4wGcASgB/wHnAagBOwH/AdEBIAEAAf8XAAEBAyQBNgP8Af8D/AH/ + A/wB/wP8Af8D/AH/A/wB/wP7Af8D+AH/A/YB/wPzAf8D8gH/A/wB/wMkATYDAAEBgAABMgE2Af4B/wG4 + AbsB/gH/AbYBuQH+Af8BswG2Af4B/wGwAbMB/gH/Ad8BhAEDAf8B7AG3AZIB/wHmAaUBNgH/AeYBogEx + Af8B6QGtAYUB/wHWASkBAAH/FwABAQMkATYD/AH/A/wB/wPHAf8DwgH/A74B/wO4Af8DtAH/A7EB/wOu + Af8DrAH/A+0B/wP8Af8DJAE2AwABAYAAATIBNgH+Af8BMgE2Af4B/wEwATQB/gH/ASwBLwH9Af8BKAEq + AfwB/wHhAY0BEAH/Ae0BuwGZAf8B6QGsAYEB/wHnAagBOgH/AeoBswGNAf8B2AEyAQAB/xcAAQEDJAE2 + A/wB/wP7Af8D/AH/A/wB/wP7Af8D+AH/A/UB/wPxAf8D7AH/A+oB/wPmAf8D/AH/AyQBNgMAAQGUAAHi + AZIBGgH/Ae4BwQGgAf8B6gGxAYkB/wHpAa4BhQH/Ae0BtwGUAf8B2wE6AQAB/xcAAQEDJAE2A/wB/wP5 + Af8DwAH/A7oB/wO0Af8DrwH/A6oB/wOlAf8D/AH/A/wB/wP8Af8D/AH/AyQBNgMAAQGUAAHmAZsBJQH/ + AfABxQGmAf8B7AG2AZEB/wHrAbMBjAH/Ae4BvAGbAf8B3wGFAQUB/xcAAQEDJAE2A/wB/wP3Af8D+QH/ + A/cB/wP3Af8D8wH/A/AB/wPqAf8D/AH/A/YB/wP0Af8DTQGRAxcBIJgAAegBoAEuAf8B8gHIAawB/wHw + AcYBqAH/AfABxQGmAf8B7wHCAaIB/wHhAY4BEQH/GAADJAE2A/AB/QP0Af8D9QH/A/UB/wP1Af8D8QH/ + A+8B/wPpAf8D/AH/A+cB/wNNAZEDFwEgAwEBApgAAeoBpgE1Af8B6AGkATIB/wHoAaABLAH/AeYBnQEp + Af8B5AGZASMB/wHiAZUBHAH/GAADIwEzA7oE8AH9A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/gB/wNN + AZEDFwEgAwEBAswAAxQBHAMjATMDJAE2AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AyQBNgMXASADAQEC + pAADCgENASICIQExAyABLwMFAQcYAAMRARcBqwIAAf8BYgFZAUgB9gMpAT80AAMGAQgBQAI/AW4DVgGz + AV4CWAHdAVICXQH0AUABhAGmAf0CAAGzAf8CAAGoAf8CQAGcAf0CUgFdAfQBWgJYAd0DVgGzAUACPwFu + AwYBCFAAAxgBIQNQAZ0BXQJUAfADoQH/A6sB/wOnAf8DlQH/AWQCXAHnA0oBigMQARYMAAG6AgAB/wHA + AYkBAAH/Ab8BiQEAAf8BrwIAAf8DKgFBMAABWwJZAcQBhwG3AeAB/wGVAcYB5gH/AZsBzQHpAf8BnAHN + AekB/wGZAccB5wH/AZUBwQHkAf8BjgG4AeAB/wGJAbAB3QH/AYEBpwHXAf8BAAGbAc8B/wEAAYwBwgH/ + AgABrgH/AVsCWQHEEAADCQEMAkYBRwGBAlkBXAHJAgAB6AH/Ax8BLSgAAy8BSgFlAl0B9APOAf8D7QH/ + A/QB/wP1Af8D9AH/A+8B/wPiAf8DugH/AWQCXAHnAyQBNQgAAcMBiAEAAf8BzwGiAQAB/wHNAaIBgQH/ + AcABjAEAAf8BsAIAAf8BTgJNAZUDMQFOAyYBOQMWAR4DAwEEHAABWwJZAcQBmAG5AdQB/wHFAccBxAH/ + AewB2AHHAf8B9gHrAeMB/wH6AfUB8QH/AfMB5wHeAf8B3wG/AaYB/wHQAaQBgQH/AcsBmgEAAf8ByAGX + AQAB/wGjAZMBjAH/AgABnAH/AVsCWQHEDAADLQFFAloBYAHeAQQBAgHrAf8BGAEZAecB/wIAAekB/wMf + AS0BXQJZAdIBXAJZAckBRwJGAYEDCQEMGAABXAJVAeoD3gH/A/MB/wPbAf8D0gH/A9sB/wPWAf8DwAH/ + A8kB/wPmAf8DxAH/AVwCVQHqCAADQAFxAcwBmQEAAf8B0AGjAYEB/wHPAaQBgwH/AcoBngEAAf8BvAGF + AQAB/wGvAgAB/wGnAgAB/wGeAgAB/wFbAlgBxgMHAQkYAAMdASoB5gHDAaUB/wHvAdYBwAH/AfsB8gHq + Af8B/gH8AfoC/wH+Af0B/wH+Af0B/AH/AfwB9gHwAf8B+AHoAdkB/wH2AeMB0QH/AfYB4gHOAf8B5gHI + Aa0B/wHOAaABAAH/Ax0BKggAAzQBVAIOAfMB/wEpASsB7gH/AZQBmQHrAf8BjQGRAekB/wIAAewB/wMf + AS0BXQJZAdIB1gGOAQ4B/wG4ARIBAAH/AWACWgHeAy4BSBQAAVwCVQHqA/AB/wPeAf8D1AH/A9IB/wPb + Af8D1gH/A78B/wOwAf8DswH/A94B/wFcAlUB6gwAA0EBcgHOAZ0BAAH/AdUBrAGMAf8BywGbAQAB/wHM + AaABAAH/AcgBmwEAAf8BxQGVAQAB/wHAAY8BAAH/AawCAAH/A0IBdhwAAVgCVgG5Ae0B0wG7Af8B+gHw + AeUB/wH9AfkB9QH/Af4B/AH6Af8B/gH9AfwB/wH9AfkB9AH/AfYB4wHPAf8B9wHlAdMB/wH2AeMB0QH/ + Ad0BuQGaAf8BVwJWAbgIAAMQARUDXwHzAZUBmQHyAf8BpQGqAe4B/wEnAYEB5gH/AZcBmgHrAf8CAAHv + Af8DHwEtAV0BWwFZAdIB2wGZARwB/wHmAaQBKwH/AcsBgAEDAf8BpgEBAQAB/wM0AVQQAAFcAlUB6gPy + Af8D4gH/A9gB/wPVAf8D3AH/A9gB/wPAAf8DswH/A7cB/wPgAf8BXAJVAeoQAAFWAlUBsQHTAagBhgH/ + AdYBrAGOAf8ByQGYAQAB/wHEAZABAAH/Ab8BigEAAf8BwgGPAQAB/wG/AYsBAAH/AV8BXQFGAfsDHQEp + HAABVQJTAbADfwH+AfcB6gHeAf8B/gH6AfcB/wH+AfwB+QH/Af0B9wHyAf8B+gHtAeIB/wHrAdABtwH/ + An8BfgH+A1QBrgwAAw0BEQNOAZkCYgFqAfkBhAGFAfQB/wGjAagB7wH/AaABpQHtAf8CAAHxAf8DHwEt + Al0BWQHSAd4BoQElAf8B3gGJAQcB/wHmAaYBKwH/AdABhwEIAf8BXwJMAfMDEAEVDAABXAJVAeoD8wH/ + A+cB/wPdAf8D2QH/A+AB/wPbAf8DxAH/A7gB/wO7Af8D4QH/AVwCVQHqEAADMQFOAdQBowEAAf8B3AG1 + AZgB/wHQAaEBAAH/AcwBmgEAAf8BzwGkAYMB/wHIAZoBAAH/AQABjAEAAf8BAAG4AQAB/wFfAU4BMAH7 + A1QBrwMHAQkYAAMnAToBYQJbAeEB8wHiAdIB/wH8AfQB7QH/AfsB8QHnAf8B6QHMAbUB/wFhAlwB3AMm + ATgQAANCAXMDPAFmAxQBGwNKAY0CXQFfAfMBKAEqAfMB/wEFAQQB9AH/Ax8BLQJdAVkB0gHhAagBgQH/ + AeABkgEQAf8B2QElAQAB/wHnAagBhAH/Ab4BHAEAAf8DSAGEDAABXAJVAeoD9AH/A+oB/wPhAf8D3QH/ + A+MB/wPeAf8DyQH/A70B/wO/Af8D4gH/AVwCVQHqEAADJgE5AdsBqwGJAf8B4QG9AaIB/wHWAaoBhwH/ + AdkBswGUAf8BzgGfAQAB/wFfAl0B+wEAAbwBAAH/AZMCAAH/AbACAAH/AaQCAAH/AWECXgHaAwMBBBwA + A1kBxwH0AeMB0AH/AfMB3wHNAf8BWwJZAcMYAAFZAVwBWQHPAZABvwGTAf8BVQFcAVUB6gNBAXIDFQEd + A0QBewNdAe0DHwEtAl0BWQHSAeQBsAGLAf8B4wGcARkB/wHdAYUBAAH/AeIBlgETAf8B2gGXARkB/wFc + AlkBzwwAAVwCVQHqA/UB/wPuAf8D5gH/A+IB/wPmAf8D4QH/A80B/wPCAf8DwgH/A+MB/wFcAlUB6hAA + AxYBHgHgAbEBjwH/AeYBxAGrAf8B4gG/AaQB/wHYAa0BjgH/A00B+gNDAXcDKwH8AbsBhAEAAf8BwAGP + AQAB/wG8AYoBAAH/AZwCAAH/AxYBHhwAAVsCWQHDAfQB4QHOAf8B8wHfAcwB/wFZAlcBwhgAAVoCXQHw + AcoB6AHIAf8BrwHZAasB/wGSAb8BlAH/A10B7QFFAUYBRQF+Aw8BFAMSARgCXQFZAdIB5wG3AZMB/wHn + AaYBIwH/AeABkAEJAf8B3gGOAQgB/wHmAa0BiAH/AV8BVAFMAfMMAAFcAlUB6gP2Af8D6wH/A94B/wPW + Af8D1QH/A9EB/wPDAf8DvAH/A8AB/wPlAf8BXAJVAeoQAAMDAQQBYQJeAdoB5AG7AZ8B/wHkAbsBnwH/ + AysB/AEAAcEBAAH/AysB/AHHAZYBAAH/AcsBngEAAf8BvAGFAQAB/wHDAZIBAAH/AaYCAAH/AyYBORQA + AyYBOAFeAlgB3QHzAd0ByQH/AfoB7gHiAf8B+QHrAd4B/wHtAdABtgH/AV8CWgHbAyYBOBAAAWACagH5 + AbYB4AGxAf8BJwHMARsB/wGSAdIBiQH/Aa0B2QGpAf8BiQG4AYsB/wNQAZ0DNQFWAmIBSQH2Ae8ByAGp + Af8B5gGmAR8B/wHiAZsBEwH/AeIBmAESAf8B5wGzAY8B/wFdAVwBTgHwDAABXAJVAeoD9wH/A+cB/wPv + Af8D9gH/A/sB/wP6Af8D8AH/A94B/wPDAf8D5gH/AVwCVQHqFAADBwEJA1QBrwFqAmYB+QEAAcUBggH/ + AbUBsAGBAf8B2AGwAZIB/wHXAa4BjwH/AckBlwEAAf8BwwGPAQAB/wHIAZsBAAH/AbECAAH/AzEBThAA + A1QBrwN/Af4B+QHsAeAB/wH9AfgB9AH/AfsB8AHmAf8B+AHnAdcB/wH5AesB3gH/AfIB2gHFAf8DfwH+ + A1QBrgwAA1wBzwG6Ad8BuAH/ASYBzAEZAf8BEgHGAQUB/wEeAcgBEgH/AagB2gGjAf8BFAGoARkB/wMo + ATwDWwHDAeYBtQGOAf8B8AHMAawB/wHlAaYBHQH/AekBsQGEAf8B4wGvAYgB/wJcAVkBzwwAAVwCVQHq + A/gB/wP+Gf8D+wH/A+oB/wFcAlUB6hwAAxsBJgGoAaYBhAH9AeIBvgGjAf8B3wG3AZoB/wHVAagBhgH/ + AdABoQEAAf8BywGaAQAB/wHOAaIBgQH/Ab8BiwEAAf8BTgJNAZUMAAFXAlYBuAH5AeMBzQH/AfsB8wHs + Af8B/gH6AfcB/wH+AfsB+AH/AfwB9QHtAf8B9wHmAdUB/wH2AeEBzAH/AfkB7AHfAf8B+QHrAd0B/wHr + Ac4BtAH/AVcCVgG4CAADSAGEAbMB2gG1Af8BogHYAZoB/wEZAcoBCwH/ARIBxgEEAf8BgAHMASEB/wGj + Ac4BowH/AVkBXAFZAc8DIgEyAUMCKwH8AfIB0QGyAf8B6wG5AY0B/wHwAckBqgH/AdgBnAEcAf8DSAGE + DAABWQJXAb8D4QH/A/4Z/wP7Af8DzwH/AVICUQGhIAADQgF2AeQBugGdAf8B5gHEAasB/wHiAb4BpAH/ + Ad4BuQGcAf8B2QGyAZMB/wHRAaMBAAH/AdEBpgGFAf8BuwIAAf8DKQE/BAADHQEqAcABxQHNAf8BmgG3 + AdwB/wEAAaYB1QH/AQABlQHKAf8BAAGHAb4B/wIAAbMB/wIAAagB/wIAAZ8B/wIAAZgB/wIAAZoB/wEA + AYMBpwH/AYgBlAGaAf8DHQEqBAADDQESA18B8wG+AeEBvgH/AZQB1AGJAf8BGgHKAQ4B/wEaAckBDAH/ + AZ4B1gGXAf8BkwHBAZYB/wM9AWkDTgGWAecBtAGOAf8B8wHTAbUB/wHpAbsBmAH/Al8BTAHzAw0BEgwA + Ax0BKgFcAlgB0QPQAf8D6AH/A/MB/wP9Af8D/AH/A+0B/wPgAf8DwgH/AVsCWQHDAxQBGyAAAwcBCQFb + AlgBxgHjAbQBkwH/Ad8BsQGOAf8B2gGrAYkB/wHaAa0BjAH/AdwBtQGYAf8B1wGvAZAB/wHMAZsBAAH/ + A00B+gQAAVwCWAHRAYcBtwHgAf8BlQHGAeYB/wGbAc0B6QH/AZwBzQHpAf8BmQHHAecB/wGVAcEB5AH/ + AY4BuAHgAf8BiQGwAd0B/wGBAacB1wH/AQABmwHPAf8BAAGMAcIB/wIAAa4B/wFcAlgB0QgAAzIBUQGg + AdUBqAH/AboB4AG7Af8BpwHaAaAB/wEpAc4BHAH/ASsBzQEfAf8BsAHZAa0B/wNdAe0DGQEjA10B7QHr + AcIBngH/Ad0BogEfAf8DMgFRFAADBQEHATUCNAFVA1QBrgFgAlsB1gFfAl0B+wFqAmYB+QFcAloBzQNS + AakDLQFGAwIBAygAAwMBBAMWAR4DJgE5AzEETgGUAdgBpwGCAf8B1wGsAYsB/wHTAacBhAH/AWIBXAFJ + AfYEAAFbAlkBxAGHAbcB4AH/AZUBxgHmAf8BnQHPAeoB/wGhAdMB7AH/AaAB0QHrAf8BmwHKAegB/wGW + AcIB5QH/AY8BugHiAf8BhwGxAd0B/wEAAaMB1AH/AQABkAHEAf8CAAGuAf8BWwJZAcQMAAMpAT8DYAHe + AbQB3AG3Af8BvAHgAboB/wG5AeEBtQH/Ac4B6gHLAf8BpAHOAaYB/wFNAk4BlgM9AWkDYAHeAykBP3wA + AykBPgFfAl0B+wFiAlwB9gMuAUgEAAMGAQgBQAI/AW4DVgGzAV4CWAHdAWUCXQH0AUABnQGmAf0BAAGZ + AdEB/wEAAZAByAH/AUABhAGmAf0BUgJdAfQBWgJYAd0DVgGzAUACPwFuAwYBCBAAAwkBDANGAX4DWwHG + ASsBOgErAfwBKwE3ASsB/ANbAcYDRQF9AwIBAwMHAQoRAAGdAdkB/wEAAZkB2AH/AQABlAHXAf8BAAGQ + AdYB/wEAAYwB1QH/AQABiAHUAf8BAAGEAdMB/wEAAYEB0gH/AgAB0QH/AgAB0QH/AgAB0AH/AgABzwH/ + AgABzwH/AgABzgH/YAADOwFjAVkCVwG/AVgCVwG/AzsBYyAAAxUBHQMjATQDJAE2AyQBNgMkATYDJAE2 + AyQBNgMkATYDJAE2AyQBNgMkATYDJAE2AyMBMwMVAR0BAAGjAdoB/wG8AesB+gH/AbwB6wH8Af8BvwHu + Af4B/wHGAfQC/wHOAfgC/wHTAfoC/wHQAfgC/wHHAfIC/wG6AekB/AH/AbMB5AH5Af8BsAHiAfgB/wGw + AeIB+AH/AgABzwH/VAADHQEpAwoBDgMBAQIBXAJVAeoDvQH/A7IB/wFcAlUB6gMBAQIDCgEOAx0BKRQA + AyMBNANZAfUBqAKmAf0D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wGoAqYB/QFfAl0B8wMj + ATMBAAGoAdsB/wG/AewB+wH/AQABzwH1Af8BAAGwAewB/wMAAf8CAAGJAf8BAAGJAb4B/wEAAZoByAH/ + AQABrgHnAf8BAAGlAeYB/wEAAZoB4QH/AQABuAHuAf8BsQHjAfgB/wIAAdAB/wgAA1IBqQHDAY4BAAH/ + AcABiwEAAf8BvgGIAQAB/wG7AYUBAAH/AbkBgwEAAf8BtAIAAf8BsgIAAf8BsQIAAf8BrgIAAf8BrQIA + Af8BqwIAAf8BqQIAAf8BqQIAAf8DUgGpDAABUAJPAZsDQAH9AWQCXAHnAxIBGQFkAlwB5wPLAf8DxwH/ + AWMCXAHnAxIBGQNcAecDQAH9AVACTwGbCAADNwFbAV0BVAFOAfABYgFcAUgB9gHlAbcBmgH/AfsC+gH/ + A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/AagCpgH9AyQBNgEAAa0B3AH/AcEB7gH7 + Af8BAAHTAfcB/wEAAdsB/AH/AgABhQH/AZQBxwH5Af8BkQHJAfkB/wEAAYUByQH/AgABrgH/AQABvQHs + Af8BAAG+Ae8B/wEAAboB7gH/AbMB4wH5Af8CAAHRAf8IAAHIAZIBADX/AakCAAH/CAADRAF7A7wB/wPe + Af8DpgH/AWUCXQH0A38B/gPEAf8DwgH/AW4CbQH+AWUCXQH0A6YB/wPSAf8DgQH/A0QBewQAAWICWAHv + AeYBuAGcAf8B6QG/AaUB/wHcAZsBAAH/AeUBuAGdAf8D/AH/A/wB/wP8Af8D+wH/A/sB/wP7Af8D+wH/ + A/sB/wP7Af8D/AH/AyQBNgEAAbIB3QH/AcMB7wH7Af8BAAHWAfgB/wEAAbYB7AH/AQABiQGqAf8B4AHy + Av8BAAGaAdgB/wIAAb4B/wEAAZgBxQH/AQABhgHFAf8BAAGbAd4B/wEAAb4B7wH/AbQB5QH5Af8CAAHS + Af8IAAHKAZQBAAv/Af4D/wH9Af8C/gH9Af8C/gH8Af8C/gH8Af8C/gH8Af8C/gH8Af8C/gH6Af8C/gH6 + Af8C/AH5Bf8BqgIAAf8IAANFAX0DfwH+A9UB/wPFAf8DywH/A9EB/wPJAf8DxwH/A8wB/wPFAf8DvQH/ + A8sB/wFvAm4B/gNFAX0EAAFtAmcB9wHrAcQBrQH/AewByAGyAf8B6gHBAakB/wHeAZ4BAAH/AecBuwGh + Af8D/AH/A/sB/wP7Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP8Af8DJAE2AQABtwHeAf8BxgHwAfwB/wEA + AdkB+AH/AQAB4gH9Af8BAAG3AdkB/wEAAbYB1QH/AZABtwHRAf8BAAHJAeQB/wEAAd8B9QH/AQAB0AHt + Af8BAAGYAdwB/wEAAboB7QH/AbYB5wH5Af8BAAGDAdMB/wgAAcwBlwEAB/8B/AP/Af0B/wL+AfwB/wL+ + AfwB/wL+AfsB/wL9AfoB/wL9AfoB/wL9AfoB/wL9AfoB/wL8AfcB/wL7AfYF/wGsAgAB/wwAA0gBhQPF + Af8DwQH/A8UB/wPHAf8DqgH/A6cB/wPBAf8DvgH/A7UB/wOqAf8DSAGFCAADQgF1AWoCZgH5AewBxwGw + Af8B7QHKAbUB/wHrAcMBqwH/Ad4BoQEAAf8B5wG6AZ8B/wP7Af8D+wH/A/sB/wP6Af8D+gH/A/gB/wP4 + Af8D/AH/AyQBNgEAAbsB3wH/AccB8QH8Af8BAAHcAfkB/wEAAbsB7QH/AQABvQHvAf8BAAHGAecB/wEA + AbgB1gH/AcIB9gH9Af8BAAHfAfcB/wEAAeIB+AH/AQAB0wHwAf8BAAGXAdwB/wGoAdwB9QH/AQABiAHU + Af8IAAHRAZwBAAX/Av4B/AH/Av4B/AH/Av4B/AH/Av0B+wH/Av0B+wH/Av0B+gH/Av0B+AH/AvsB+QH/ + AfsB+gH3Af8B+wH6AfYB/wH7AfgB9AX/AbACAAH/BAABXAJaAc0BXwJYAeMBYQJWAe4DzwH/A8YB/wPM + Af8BWwJYAcYDLAFEAywBRAFbAlgBxgPBAf8DvAH/A7kB/wFhAlYB7gFbAlgB4wNaAc0EAANDAXgDfwH+ + Ae0ByAGzAf8B7QHNAbgB/wHpAb4BowH/AdYBjgEAAf8D/AH/A/wB/wP8Af8D+wH/A/kB/wP5Af8D+AH/ + A/wB/wMkATYBAAG/AeAB/wHIAfMB/AH/AQAB3wH5Af8BiQHmAf0B/wGVAecC/wGaAeUC/wEAAcoB5wH/ + AQABywHnAf8BxwH3Af0B/wEAAdwB9QH/AQAB4QH3Af8BAAHUAfEB/wEAAZkB3gH/AQABjQHWAf8IAAHU + AZ4BAAX/Av4B/AH/Av0B+wH/Av0B/AH/Av0B+wH/Av0B+QH/AvwB+AH/AfsB+QH3Af8B+wH5AfUB/wH7 + AfgB9AH/AfsB9wHyAf8B+wH1AfIF/wGyAgAB/wQAAagCpgH9A+IB/wPSAf8DxgH/A80B/wOxAf8DLAFE + CAADLAFEA6gB/wPCAf8DtwH/A8AB/wPSAf8DQAH9BwABAQNMAZIB4AGpAYgB/wHrAccBsAH/Ad0BoQEA + Af8BvAGlAZUB/wOsAf8D0AH/A9QB/wPvAf8D+QH/A/YB/wP2Af8D/AH/AyQBNgEAAcIB4QH/AckB8wH8 + Af8BywHzAf0B/wHUAfYB/gH/AdcB9gL/AdgB9AL/AeAB+AL/AakB4wH1Af8BAAHTAe4B/wHHAfcB/QH/ + AQAB3AH1Af8BAAHiAfcB/wEAAdYB8gH/AQABmAHeAf8DIQEwBAAB1QGgAQAF/wL9AfwB/wL9AfsB/wL9 + AfoB/wL8AfkB/wH8AfsB9wH/AfsB+QH1Af8B+wH4AfQB/wH7AfcB8wH/AfsB9QHyAf8B+gHzAe8B/wH4 + AfIB7AX/AbUCAAH/BAABqAKmAf0D6QH/A9YB/wPJAf8DzgH/A6UB/wMsAUQIAAMsAUQDrAH/A8QB/wO6 + Af8DxgH/A90B/wNAAf0HAAEBAyQBNgHwAdYBxgH/Ad4BrQGQAf8BxAGvAaMB/wPVAf8DuwH/A6YB/wOg + Af8DkAH/A8kB/wPzAf8D8gH/A/wB/wMkATYBAAHDAeEB/wGIAaABqAH/A5EB/wOOAf8BAAG5AdwB/wEA + AbgB3wH/AQABtQHeAf8BAAGxAd0B/wEAAbAB3gH/AQAB1AHuAf8BxAH2Af0B/wEAAd0B9gH/AQABygHt + Af8BAAGjAdcB/wFgAlkB7AMbASYB2AGiAQAF/wL9AfoB/wL8AfoB/wH8AfsB+QH/AfsB+gH2Af8B+wH4 + AfUB/wH7AfcB9AH/AfsB9gHxAf8B+AH0Ae4B/wH3AfIB6wH/AfcB8AHqAf8B9gHsAegF/wG3AYEBAAH/ + BAABXAJaAc0BXwJYAeMBYQJWAe4D2AH/A80B/wO8Af8BWwJYAcYDLAFEAywBRAFbAlgBxgPDAf8DwgH/ + A80B/wFhAlYB7gFfAlgB4wFcAloBzQcAAQEDJAE2A/wB/wP7Af8DrAH/A8sB/wPSAf8DyQH/A9IB/wPG + Af8DjwH/A+8B/wPtAf8D/AH/AyQBNgQAAVsCWQHDA8YB/wOUAf8DBgEIEAADNwFaAQAB0wHrAf8BsgHj + AfkB/wGLAcAB5wH/Aa4B0wH2Af8BxAHgAfwB/wNnAfcB2QGjAQAF/wH8AfsB+QH/AfwB+wH4Af8B+wH5 + AfcB/wH7AfcB9AH/AfoB9wHyAf8B+QH1AfAB/wH3AfMB7QH/AfYB7wHqAf8B9QHrAecB/wHzAeoB5AH/ + AfIB5wHeBf8BugGFAQAB/wwAA0gBhQPUAf8DzAH/A8kB/wO6Af8DnAH/A6EB/wPCAf8DxgH/A8EB/wO3 + Af8DSAGFDwABAQMkATYD/AH/A/sB/wPbAf8DsgH/A9YB/wOgAf8DkgH/A8AB/wOKAf8D6gH/A+YB/wP8 + Af8DJAE2BAADVAGuA8QB/wOhAf8DHQEpEAADHQEpAQABmQGpAf8BAAG+AecB/wG0AdIB8AH/AeUB8wL/ + AawB0gHvAf8BXwJXAegB2wGkAQA1/wG9AYcBAAH/CAADRQF9A38B/gPcAf8D1AH/A9kB/wPbAf8D1gH/ + A9QB/wPZAf8D0gH/A8sB/wPIAf8BegJ5Af4DRQF9CwABAQMkATYD/AH/A/kB/wPaAf8DtQH/A+YB/wOa + Af8DsAH/A68B/wO9Af8D/AH/A/wB/wP8Af8DJAE2BAADQgF1A7oB/wO/Af8BXgJYAd0DFgEfAwQBBQME + AQUDFgEfAWUCXgHlA6gB/wEAAaQBswH/AQABpQHYAf8BhQGxAdsB/wEAAZ0B0AH/AzgBXgHcAacBAAH/ AdwBpwEAAf8B3AGnAQAB/wHcAacBAAH/AdwBpwEAAf8B3AGnAQAB/wHcAacBAAH/AdwBpwEAAf8B3AGn - AQAB/wHcAacBAAH/AdwBpwEAAf8B3AGnAQAB/wHcAacBAAH/AdwBpwEAAf8B3AGnAQAB/wHAAYsBAAH/ - CAADRAF7A9wB/wPtAf8D2wH/AWUCXQH0A38B/gPWAf8D1AH/A38B/gFlAl0B9APLAf8D5wH/A7cB/wNE - AXsLAAEBAyQBNgP8Af8D9wH/A+8B/wOmAf8D4QH/A9IB/wO0Af8D6gH/A/wB/wP2Af8D9AH/AU0CTAGR - AxcBIAQAAwkBDAFfAloB2wPEAf8DvgH/A6EB/wOWAf8DkwH/A5cB/wOuAf8DrgH/AV8CWgHbAwcBCQwA - AagBpgGDAf0B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5 - AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wGoAY4BQAH9 - DAABUAJPAZsBqAKmAf0BZAJcAecDEgEZAWQCXAHnA94B/wPdAf8BZAJcAecDEgEZAWQCXAHnAacCpQH9 - AVACTwGbEAADJAE2AagCpgH9A/QB/wP1Af8D1AH/A6UB/wOdAf8DvgH/A+kB/wP8Af8D5wH/AU0CTAGR - AxcBIAMBAQIIAAMhATABYAJaAd4DvAH/A8oB/wPMAf8DygH/A8IB/wOtAf8BYAJaAd4DIQEwEAADPgFr - AWUCXQH0AdwBpwEAAf8B3AGmAQAB/wHaAaQBAAH/AdgBogEAAf8B1QGgAQAB/wHUAZ4BAAH/AdIBnQEA - Af8BzwGaAQAB/wHOAZkBAAH/AcsBlgEAAf8ByQGUAQAB/wFlAl0B9AM+AWsQAAMdASkDCgEOAwEBAgFc - AlUB6gPlAf8D5AH/AVwCVQHqAwEBAgMKAQ4DHQEpFAADIwEzAV0CVAHwAagCpgH9A/wB/wP8Af8D/AH/ - A/wB/wP8Af8D/AH/A/gB/wFNAkwBkQMXASADAQECEAADCQEMAUcCRgGBAVcCVQG6AVwCWQHMAVwCWQHM - AVcCVQG6AUcCRgGBAwkBDGwAAzsBYwFZAlcBvwFZAlcBvwM7AWMgAAMUARwDIwEzAyQBNgMkATYDJAE2 - AyQBNgMkATYDJAE2AyQBNgMkATYDFwEgAwEBAggAAUIBTQE+BwABPgMAASgDAAFAAwABMAMAAQEBAAEB - BQABgAEBFgAD/wEAAv8BgAEBBgABgAEBBwABAS0AAR8HAAEfBwABHwYAAfgBHwYAAfgBHwEAAQEEAAH4 - AR8BgAEBBAAB+AEfAYABAwQAAv8BgAEHBAAB/AE/AQ8B/wGAAQEC/wHgAgcB/wGAAQEB4AH/AcABAwEA - AT8BgAEBAcABDwHAAQMBAAEfAYABAQGAAQcBwAEDAYABHwHAAQMBAAEDAcABAwHAAQ8B4AEHAQABAQHA - AQMBwAEDAfABDwEAAQEBwAEDAcABAQH8AT8BAAEBAcABAwHAAQEB/AE/AQABAQHAAQMBwAEBAfABDwEA - AQEBwAEDAeABAQHgAQcBAAEBAcABAwH4AQEBwAEDAQABAQHAAQMB/AEAAYABAQEAAQEBwAEDAfwBAAGA - AQEBgAEDAeABBwH+AQABgAEBAcABBwP/AfABgAEBAeABDwEAAQMC/wH8AT8BwAIAAQMC/wHgAQcBwAIA - AQMBAAEBAcABAwMAAQMBAAEBAYABAQMAAQMBAAEBAYABAQMAAQMBAAEBAcABAwMAAQMBAAEBAgABgAIA - AQMBAAIBAoACAAEBAQACAQKABAABAQIAAYABAAGHAYABAAEBAcABAwGAAQABhwGAAQABAQGAAQEBgAEA - AYACAAEBAYABAQGAAQABgAEHAQABAQHAAQMBwAEAAcABDwEAAQEB4AEHAcABAQHgAR8C/wH8AT8BwAED - Cw== + AQAB/wHcAacBAAH/AdwBpwEAAf8B3AGnAQAB/wHcAacBAAH/AdwBpwEAAf8BwAGLAQAB/wgAA0QBewPc + Af8D7QH/A9sB/wFlAl0B9AN/Af4D1gH/A9QB/wN/Af4BZQJdAfQDywH/A+cB/wO3Af8DRAF7CwABAQMk + ATYD/AH/A/cB/wPvAf8DpgH/A+EB/wPSAf8DtAH/A+oB/wP8Af8D9gH/A/QB/wFNAkwBkQMXASAEAAMJ + AQwBXwJaAdsDxAH/A74B/wOhAf8DlgH/A5MB/wOXAf8DrgH/A64B/wFfAloB2wMHAQkMAAGoAaYBgwH9 + AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5 + AZIB/wHoAbkBkgH/AegBuQGSAf8B6AG5AZIB/wHoAbkBkgH/AegBuQGSAf8BqAGOAUAB/QwAAVACTwGb + AagCpgH9AWQCXAHnAxIBGQFkAlwB5wPeAf8D3QH/AWQCXAHnAxIBGQFkAlwB5wGnAqUB/QFQAk8BmxAA + AyQBNgGoAqYB/QP0Af8D9QH/A9QB/wOlAf8DnQH/A74B/wPpAf8D/AH/A+cB/wFNAkwBkQMXASADAQEC + CAADIQEwAWACWgHeA7wB/wPKAf8DzAH/A8oB/wPCAf8DrQH/AWACWgHeAyEBMBAAAz4BawFlAl0B9AHc + AacBAAH/AdwBpgEAAf8B2gGkAQAB/wHYAaIBAAH/AdUBoAEAAf8B1AGeAQAB/wHSAZ0BAAH/Ac8BmgEA + Af8BzgGZAQAB/wHLAZYBAAH/AckBlAEAAf8BZQJdAfQDPgFrEAADHQEpAwoBDgMBAQIBXAJVAeoD5QH/ + A+QB/wFcAlUB6gMBAQIDCgEOAx0BKRQAAyMBMwFdAlQB8AGoAqYB/QP8Af8D/AH/A/wB/wP8Af8D/AH/ + A/wB/wP4Af8BTQJMAZEDFwEgAwEBAhAAAwkBDAFHAkYBgQFXAlUBugFcAlkBzAFcAlkBzAFXAlUBugFH + AkYBgQMJAQxsAAM7AWMBWQJXAb8BWQJXAb8DOwFjIAADFAEcAyMBMwMkATYDJAE2AyQBNgMkATYDJAE2 + AyQBNgMkATYDJAE2AxcBIAMBAQIIAAFCAU0BPgcAAT4DAAEoAwABQAMAATADAAEBAQABAQUAAYABARYA + A/8BAAL/AYABAQYAAYABAQcAAQEtAAEfBwABHwcAAR8GAAH4AR8GAAH4AR8BAAEBBAAB+AEfAYABAQQA + AfgBHwGAAQMEAAL/AYABBwQAAfwBPwEPAf8BgAEBAv8B4AIHAf8BgAEBAeAB/wHAAQMBAAE/AYABAQHA + AQ8BwAEDAQABHwGAAQEBgAEHAcABAwGAAR8BwAEDAQABAwHAAQMBwAEPAeABBwEAAQEBwAEDAcABAwHw + AQ8BAAEBAcABAwHAAQEB/AE/AQABAQHAAQMBwAEBAfwBPwEAAQEBwAEDAcABAQHwAQ8BAAEBAcABAwHg + AQEB4AEHAQABAQHAAQMB+AEBAcABAwEAAQEBwAEDAfwBAAGAAQEBAAEBAcABAwH8AQABgAEBAYABAwHg + AQcB/gEAAYABAQHAAQcD/wHwAYABAQHgAQ8BAAEDAv8B/AE/AcACAAEDAv8B4AEHAcACAAEDAQABAQHA + AQMDAAEDAQABAQGAAQEDAAEDAQABAQGAAQEDAAEDAQABAQHAAQMDAAEDAQABAQIAAYACAAEDAQACAQKA + AgABAQEAAgECgAQAAQECAAGAAQABhwGAAQABAQHAAQMBgAEAAYcBgAEAAQEBgAEBAYABAAGAAgABAQGA + AQEBgAEAAYABBwEAAQEBwAEDAcABAAHAAQ8BAAEBAeABBwHAAQEB4AEfAv8B/AE/AcABAws= diff --git a/trunk/ProcessHacker/Forms/SysInfoWindow.Designer.cs b/trunk/ProcessHacker/Forms/SysInfoWindow.Designer.cs index 55c366ac0..9d0d8b624 100644 --- a/trunk/ProcessHacker/Forms/SysInfoWindow.Designer.cs +++ b/trunk/ProcessHacker/Forms/SysInfoWindow.Designer.cs @@ -31,9 +31,12 @@ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SysInfoWindow)); this.gboxCPUPlotter = new System.Windows.Forms.GroupBox(); this.tableCPUs = new System.Windows.Forms.TableLayoutPanel(); + this.plotterCPU = new ProcessHacker.Components.Plotter(); this.tableGraphs = new System.Windows.Forms.TableLayoutPanel(); this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.plotterMemory = new ProcessHacker.Components.Plotter(); this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.plotterIO = new ProcessHacker.Components.Plotter(); this.checkShowOneGraphPerCPU = new System.Windows.Forms.CheckBox(); this.flowInfo = new System.Windows.Forms.FlowLayoutPanel(); this.groupBox3 = new System.Windows.Forms.GroupBox(); @@ -120,9 +123,6 @@ this.labelCPUSystemCalls = new System.Windows.Forms.Label(); this.label41 = new System.Windows.Forms.Label(); this.labelCPUInterrupts = new System.Windows.Forms.Label(); - this.plotterMemory = new ProcessHacker.Components.Plotter(); - this.plotterIO = new ProcessHacker.Components.Plotter(); - this.plotterCPU = new ProcessHacker.Components.Plotter(); this.gboxCPUPlotter.SuspendLayout(); this.tableGraphs.SuspendLayout(); this.groupBox1.SuspendLayout(); @@ -170,6 +170,33 @@ this.tableCPUs.TabIndex = 3; this.tableCPUs.Visible = false; // + // plotterCPU + // + this.plotterCPU.BackColor = System.Drawing.Color.Black; + this.plotterCPU.Data1 = null; + this.plotterCPU.Data2 = null; + this.plotterCPU.Dock = System.Windows.Forms.DockStyle.Fill; + this.plotterCPU.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(128)))), ((int)(((byte)(64))))); + this.plotterCPU.GridSize = new System.Drawing.Size(12, 12); + this.plotterCPU.LineColor1 = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); + this.plotterCPU.LineColor2 = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.plotterCPU.Location = new System.Drawing.Point(3, 16); + this.plotterCPU.LongData1 = null; + this.plotterCPU.LongData2 = null; + this.plotterCPU.MoveStep = 3; + this.plotterCPU.Name = "plotterCPU"; + this.plotterCPU.OverlaySecondLine = false; + this.plotterCPU.ShowGrid = true; + this.plotterCPU.Size = new System.Drawing.Size(806, 40); + this.plotterCPU.TabIndex = 0; + this.plotterCPU.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.plotterCPU.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); + this.plotterCPU.TextMargin = new System.Windows.Forms.Padding(3); + this.plotterCPU.TextPadding = new System.Windows.Forms.Padding(3); + this.plotterCPU.TextPosition = System.Drawing.ContentAlignment.TopLeft; + this.plotterCPU.UseLongData = false; + this.plotterCPU.UseSecondLine = true; + // // tableGraphs // this.tableGraphs.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) @@ -203,6 +230,33 @@ this.groupBox1.TabStop = false; this.groupBox1.Text = "Commit, Physical Memory"; // + // plotterMemory + // + this.plotterMemory.BackColor = System.Drawing.Color.Black; + this.plotterMemory.Data1 = null; + this.plotterMemory.Data2 = null; + this.plotterMemory.Dock = System.Windows.Forms.DockStyle.Fill; + this.plotterMemory.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(128)))), ((int)(((byte)(64))))); + this.plotterMemory.GridSize = new System.Drawing.Size(12, 12); + this.plotterMemory.LineColor1 = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); + this.plotterMemory.LineColor2 = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.plotterMemory.Location = new System.Drawing.Point(3, 16); + this.plotterMemory.LongData1 = null; + this.plotterMemory.LongData2 = null; + this.plotterMemory.MoveStep = 3; + this.plotterMemory.Name = "plotterMemory"; + this.plotterMemory.OverlaySecondLine = true; + this.plotterMemory.ShowGrid = true; + this.plotterMemory.Size = new System.Drawing.Size(806, 40); + this.plotterMemory.TabIndex = 5; + this.plotterMemory.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.plotterMemory.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); + this.plotterMemory.TextMargin = new System.Windows.Forms.Padding(3); + this.plotterMemory.TextPadding = new System.Windows.Forms.Padding(3); + this.plotterMemory.TextPosition = System.Drawing.ContentAlignment.TopLeft; + this.plotterMemory.UseLongData = true; + this.plotterMemory.UseSecondLine = true; + // // groupBox2 // this.groupBox2.Controls.Add(this.plotterIO); @@ -214,6 +268,33 @@ this.groupBox2.TabStop = false; this.groupBox2.Text = "I/O (R+O, W)"; // + // plotterIO + // + this.plotterIO.BackColor = System.Drawing.Color.Black; + this.plotterIO.Data1 = null; + this.plotterIO.Data2 = null; + this.plotterIO.Dock = System.Windows.Forms.DockStyle.Fill; + this.plotterIO.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(128)))), ((int)(((byte)(64))))); + this.plotterIO.GridSize = new System.Drawing.Size(12, 12); + this.plotterIO.LineColor1 = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); + this.plotterIO.LineColor2 = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.plotterIO.Location = new System.Drawing.Point(3, 16); + this.plotterIO.LongData1 = null; + this.plotterIO.LongData2 = null; + this.plotterIO.MoveStep = 3; + this.plotterIO.Name = "plotterIO"; + this.plotterIO.OverlaySecondLine = true; + this.plotterIO.ShowGrid = true; + this.plotterIO.Size = new System.Drawing.Size(806, 40); + this.plotterIO.TabIndex = 5; + this.plotterIO.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); + this.plotterIO.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); + this.plotterIO.TextMargin = new System.Windows.Forms.Padding(3); + this.plotterIO.TextPadding = new System.Windows.Forms.Padding(3); + this.plotterIO.TextPosition = System.Drawing.ContentAlignment.TopLeft; + this.plotterIO.UseLongData = true; + this.plotterIO.UseSecondLine = true; + // // checkShowOneGraphPerCPU // this.checkShowOneGraphPerCPU.AutoSize = true; @@ -1204,72 +1285,6 @@ this.labelCPUInterrupts.TabIndex = 1; this.labelCPUInterrupts.Text = "value"; // - // plotterMemory - // - this.plotterMemory.BackColor = System.Drawing.Color.Black; - this.plotterMemory.Dock = System.Windows.Forms.DockStyle.Fill; - this.plotterMemory.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(128)))), ((int)(((byte)(64))))); - this.plotterMemory.GridSize = new System.Drawing.Size(12, 12); - this.plotterMemory.IsMoved = true; - this.plotterMemory.LineColor1 = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); - this.plotterMemory.LineColor2 = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); - this.plotterMemory.Location = new System.Drawing.Point(3, 16); - this.plotterMemory.MoveStep = 3; - this.plotterMemory.Name = "plotterMemory"; - this.plotterMemory.OverlaySecondLine = true; - this.plotterMemory.Size = new System.Drawing.Size(806, 40); - this.plotterMemory.TabIndex = 5; - this.plotterMemory.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); - this.plotterMemory.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); - this.plotterMemory.TextMargin = new System.Windows.Forms.Padding(3); - this.plotterMemory.TextPadding = new System.Windows.Forms.Padding(3); - this.plotterMemory.TextPosition = System.Drawing.ContentAlignment.TopLeft; - this.plotterMemory.UseSecondLine = true; - // - // plotterIO - // - this.plotterIO.BackColor = System.Drawing.Color.Black; - this.plotterIO.Dock = System.Windows.Forms.DockStyle.Fill; - this.plotterIO.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(128)))), ((int)(((byte)(64))))); - this.plotterIO.GridSize = new System.Drawing.Size(12, 12); - this.plotterIO.IsMoved = true; - this.plotterIO.LineColor1 = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); - this.plotterIO.LineColor2 = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); - this.plotterIO.Location = new System.Drawing.Point(3, 16); - this.plotterIO.MoveStep = 3; - this.plotterIO.Name = "plotterIO"; - this.plotterIO.OverlaySecondLine = true; - this.plotterIO.Size = new System.Drawing.Size(806, 40); - this.plotterIO.TabIndex = 5; - this.plotterIO.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); - this.plotterIO.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); - this.plotterIO.TextMargin = new System.Windows.Forms.Padding(3); - this.plotterIO.TextPadding = new System.Windows.Forms.Padding(3); - this.plotterIO.TextPosition = System.Drawing.ContentAlignment.TopLeft; - this.plotterIO.UseSecondLine = true; - // - // plotterCPU - // - this.plotterCPU.BackColor = System.Drawing.Color.Black; - this.plotterCPU.Dock = System.Windows.Forms.DockStyle.Fill; - this.plotterCPU.GridColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(128)))), ((int)(((byte)(64))))); - this.plotterCPU.GridSize = new System.Drawing.Size(12, 12); - this.plotterCPU.IsMoved = true; - this.plotterCPU.LineColor1 = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); - this.plotterCPU.LineColor2 = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); - this.plotterCPU.Location = new System.Drawing.Point(3, 16); - this.plotterCPU.MoveStep = 3; - this.plotterCPU.Name = "plotterCPU"; - this.plotterCPU.OverlaySecondLine = false; - this.plotterCPU.Size = new System.Drawing.Size(806, 40); - this.plotterCPU.TabIndex = 0; - this.plotterCPU.TextBoxColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(0))))); - this.plotterCPU.TextColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(255)))), ((int)(((byte)(0))))); - this.plotterCPU.TextMargin = new System.Windows.Forms.Padding(3); - this.plotterCPU.TextPadding = new System.Windows.Forms.Padding(3); - this.plotterCPU.TextPosition = System.Drawing.ContentAlignment.TopLeft; - this.plotterCPU.UseSecondLine = true; - // // SysInfoWindow // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -1280,6 +1295,7 @@ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MinimumSize = new System.Drawing.Size(357, 436); this.Name = "SysInfoWindow"; + this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; this.Text = "System Information"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SysInfoWindow_FormClosing); this.gboxCPUPlotter.ResumeLayout(false); diff --git a/trunk/ProcessHacker/Forms/SysInfoWindow.cs b/trunk/ProcessHacker/Forms/SysInfoWindow.cs index 0a4330f83..f38fa9613 100644 --- a/trunk/ProcessHacker/Forms/SysInfoWindow.cs +++ b/trunk/ProcessHacker/Forms/SysInfoWindow.cs @@ -22,12 +22,9 @@ */ using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; using System.Drawing; -using System.Text; using System.Windows.Forms; +using ProcessHacker.Components; namespace ProcessHacker { @@ -37,42 +34,57 @@ namespace ProcessHacker private int _noOfCPUs = Program.HackerWindow.ProcessProvider.System.NumberOfProcessors; private int _pages = Program.HackerWindow.ProcessProvider.System.NumberOfPhysicalPages; private int _pageSize = Program.HackerWindow.ProcessProvider.System.PageSize; - private DeltaManager _deltaManager = new DeltaManager(new Int64Subtractor()); - private int _runCount = 0; public SysInfoWindow() { InitializeComponent(); - // intialize delta manager - _deltaManager.Add("clock", (long)Win32.GetTickCount() * 10000); - _deltaManager.Add("cpu_kernel", 0); - _deltaManager.Add("cpu_user", 0); - _deltaManager.Add("cpu_other", 0); - _deltaManager.Add("contextswitches", 0); - _deltaManager.Add("io_r", 0); - _deltaManager.Add("io_w", 0); - _deltaManager.Add("io_o", 0); + this.Location = Properties.Settings.Default.SysInfoWindowLocation; + this.Size = Properties.Settings.Default.SysInfoWindowSize; + + plotterCPU.Data1 = Program.HackerWindow.ProcessProvider.FloatHistory["Kernel"]; + plotterCPU.Data2 = Program.HackerWindow.ProcessProvider.FloatHistory["User"]; + plotterCPU.GetToolTip = i => + Program.HackerWindow.ProcessProvider.MostCpuHistory[i] + "\n" + + ((plotterCPU.Data1[i] + plotterCPU.Data2[i]) * 100).ToString("N2") + + "% (K " + (plotterCPU.Data1[i] * 100).ToString("N2") + + "%, U " + (plotterCPU.Data2[i] * 100).ToString("N2") + "%)"; + plotterIO.LongData1 = Program.HackerWindow.ProcessProvider.LongHistory[SystemStats.IoReadOther]; + plotterIO.LongData2 = Program.HackerWindow.ProcessProvider.LongHistory[SystemStats.IoWrite]; + plotterIO.GetToolTip = i => + Program.HackerWindow.ProcessProvider.MostIoHistory[i] + "\n" + + "R+O: " + Misc.GetNiceSizeName(plotterIO.LongData1[i]) + + ", W: " + Misc.GetNiceSizeName(plotterIO.LongData2[i]); + plotterMemory.LongData1 = Program.HackerWindow.ProcessProvider.LongHistory[SystemStats.Commit]; + plotterMemory.LongData2 = Program.HackerWindow.ProcessProvider.LongHistory[SystemStats.PhysicalMemory]; + plotterMemory.GetToolTip = i => + "Commit: " + Misc.GetNiceSizeName(plotterMemory.LongData1[i]) + "\n" + + "Phys. Memory: " + Misc.GetNiceSizeName(plotterMemory.LongData2[i]); // create a plotter per CPU - _cpuPlotters = new ProcessHacker.Components.Plotter[_noOfCPUs]; + _cpuPlotters = new Plotter[_noOfCPUs]; tableCPUs.ColumnCount = _noOfCPUs; tableCPUs.ColumnStyles.Clear(); tableCPUs.Dock = DockStyle.Fill; for (int i = 0; i < _cpuPlotters.Length; i++) { - tableCPUs.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 1.0f / _noOfCPUs)); - _cpuPlotters[i] = new ProcessHacker.Components.Plotter(); - _cpuPlotters[i].BackColor = Color.Black; - _cpuPlotters[i].Dock = DockStyle.Fill; - _cpuPlotters[i].Margin = new Padding(i == 0 ? 0 : 3, 0, 0, 0); - _cpuPlotters[i].UseSecondLine = true; - tableCPUs.Controls.Add(_cpuPlotters[i], i, 0); + Plotter plotter; - _deltaManager.Add("cpu_" + i.ToString() + "_kernel", 0); - _deltaManager.Add("cpu_" + i.ToString() + "_user", 0); - _deltaManager.Add("cpu_" + i.ToString() + "_other", 0); + tableCPUs.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 1.0f / _noOfCPUs)); + _cpuPlotters[i] = plotter = new ProcessHacker.Components.Plotter(); + plotter.BackColor = Color.Black; + plotter.Dock = DockStyle.Fill; + plotter.Margin = new Padding(i == 0 ? 0 : 3, 0, 0, 0); + plotter.UseSecondLine = true; + plotter.Data1 = Program.HackerWindow.ProcessProvider.FloatHistory[i.ToString() + " Kernel"]; + plotter.Data2 = Program.HackerWindow.ProcessProvider.FloatHistory[i.ToString() + " User"]; + plotter.GetToolTip = j => + Program.HackerWindow.ProcessProvider.MostCpuHistory[j] + "\n" + + ((plotter.Data1[j] + plotter.Data2[j]) * 100).ToString("N2") + + "% (K " + (plotter.Data1[j] * 100).ToString("N2") + + "%, U " + (plotter.Data2[j] * 100).ToString("N2") + "%)"; + tableCPUs.Controls.Add(plotter, i, 0); } tableCPUs.Visible = true; @@ -81,58 +93,29 @@ namespace ProcessHacker if (_noOfCPUs == 1) checkShowOneGraphPerCPU.Enabled = false; - } - public bool Started { get; private set; } + this.UpdateGraphs(); + this.UpdateInfo(); - public void Start() - { - if (this.Started) - throw new Exception("Already started"); - - this.Started = true; - _runCount = 0; Program.HackerWindow.ProcessProvider.Updated += new ProcessSystemProvider.ProviderUpdateOnce(ProcessProvider_Updated); } - public void Stop() - { - if (!this.Started) - throw new Exception("Not started"); - - Program.HackerWindow.ProcessProvider.Updated -= - new ProcessSystemProvider.ProviderUpdateOnce(ProcessProvider_Updated); - this.Started = false; - } - private void SysInfoWindow_FormClosing(object sender, FormClosingEventArgs e) { - this.Stop(); - Properties.Settings.Default.ShowOneGraphPerCPU = checkShowOneGraphPerCPU.Checked; - e.Cancel = true; - this.Hide(); - } - - private void UpdateDeltas() - { - Win32.SYSTEM_PERFORMANCE_INFORMATION perfInfo = Program.HackerWindow.ProcessProvider.Performance; - - _deltaManager.Update("cpu_kernel", Program.HackerWindow.ProcessProvider.ProcessorPerf.KernelTime); - _deltaManager.Update("cpu_user", Program.HackerWindow.ProcessProvider.ProcessorPerf.UserTime); - _deltaManager.Update("cpu_other", Program.HackerWindow.ProcessProvider.ProcessorPerf.IdleTime + - Program.HackerWindow.ProcessProvider.ProcessorPerf.DpcTime + - Program.HackerWindow.ProcessProvider.ProcessorPerf.InterruptTime); - _deltaManager.Update("contextswitches", perfInfo.ContextSwitches); - _deltaManager.Update("io_r", perfInfo.IoReadTransferCount); - _deltaManager.Update("io_w", perfInfo.IoWriteTransferCount); - _deltaManager.Update("io_o", perfInfo.IoOtherTransferCount); + if (this.WindowState == FormWindowState.Normal) + { + Properties.Settings.Default.SysInfoWindowLocation = this.Location; + Properties.Settings.Default.SysInfoWindowSize = this.Size; + } + + Program.HackerWindow.ProcessProvider.Updated -= + new ProcessSystemProvider.ProviderUpdateOnce(ProcessProvider_Updated); + Properties.Settings.Default.ShowOneGraphPerCPU = checkShowOneGraphPerCPU.Checked; } private void UpdateGraphs() { - Win32.SYSTEM_PERFORMANCE_INFORMATION perfInfo = Program.HackerWindow.ProcessProvider.Performance; - plotterCPU.LineColor1 = Properties.Settings.Default.PlotterCPUKernelColor; plotterCPU.LineColor2 = Properties.Settings.Default.PlotterCPUUserColor; plotterIO.LineColor1 = Properties.Settings.Default.PlotterIOROColor; @@ -140,69 +123,35 @@ namespace ProcessHacker plotterMemory.LineColor1 = Properties.Settings.Default.PlotterMemoryPrivateColor; plotterMemory.LineColor2 = Properties.Settings.Default.PlotterMemoryWSColor; - // update the CPU graph - long sysKernel = _deltaManager.GetDelta("cpu_kernel"); - long sysUser = _deltaManager.GetDelta("cpu_user"); - long sysOther = _deltaManager.GetDelta("cpu_other"); - float kernelUsage = (float)sysKernel / (sysKernel + sysUser + sysOther); - float userUsage = (float)sysUser / (sysKernel + sysUser + sysOther); - - plotterCPU.Add(kernelUsage, userUsage); - plotterCPU.Text = ((kernelUsage + userUsage) * 100).ToString("F2") + - "% (K: " + (kernelUsage * 100).ToString("F2") + - "%, U: " + (userUsage * 100).ToString("F2") + "%)"; - - // update the individual CPU graphs - for (int i = 0; i < _noOfCPUs; i++) + for (int i = 0; i < _cpuPlotters.Length; i++) { _cpuPlotters[i].LineColor1 = Properties.Settings.Default.PlotterCPUKernelColor; _cpuPlotters[i].LineColor2 = Properties.Settings.Default.PlotterCPUUserColor; - - _deltaManager.Update("cpu_" + i.ToString() + "_kernel", - Program.HackerWindow.ProcessProvider.ProcessorPerfArray[i].KernelTime); - _deltaManager.Update("cpu_" + i.ToString() + "_user", - Program.HackerWindow.ProcessProvider.ProcessorPerfArray[i].UserTime); - _deltaManager.Update("cpu_" + i.ToString() + "_other", - Program.HackerWindow.ProcessProvider.ProcessorPerfArray[i].IdleTime + - Program.HackerWindow.ProcessProvider.ProcessorPerfArray[i].DpcTime + - Program.HackerWindow.ProcessProvider.ProcessorPerfArray[i].InterruptTime); - - long cpuKernel = _deltaManager.GetDelta("cpu_" + i.ToString() + "_kernel"); - long cpuUser = _deltaManager.GetDelta("cpu_" + i.ToString() + "_user"); - long cpuOther = _deltaManager.GetDelta("cpu_" + i.ToString() + "_other"); - float cpuKernelUsage = (float)cpuKernel / (cpuKernel + cpuUser + cpuOther); - float cpuUserUsage = (float)cpuUser / (cpuKernel + cpuUser + cpuOther); - - _cpuPlotters[i].Add(cpuKernelUsage, cpuUserUsage); - _cpuPlotters[i].Text = ((cpuKernelUsage + cpuUserUsage) * 100).ToString("F2") + - "% (K: " + (cpuKernelUsage * 100).ToString("F2") + - "%, U: " + (cpuUserUsage * 100).ToString("F2") + "%)"; + _cpuPlotters[i].Text = ((_cpuPlotters[i].Data1[0] + _cpuPlotters[i].Data2[0]) * 100).ToString("F2") + + "% (K: " + (_cpuPlotters[i].Data1[0] * 100).ToString("F2") + + "%, U: " + (_cpuPlotters[i].Data2[0] * 100).ToString("F2") + "%)"; + _cpuPlotters[i].MoveGrid(); + _cpuPlotters[i].Draw(); } - // this hack is needed for some reason - if (_runCount < 4) - { - _deltaManager.SetDelta("io_r", 0); - _deltaManager.SetDelta("io_w", 0); - _deltaManager.SetDelta("io_o", 0); - } + plotterCPU.Text = ((plotterCPU.Data1[0] + plotterCPU.Data2[0]) * 100).ToString("F2") + + "% (K: " + (plotterCPU.Data1[0] * 100).ToString("F2") + + "%, U: " + (plotterCPU.Data2[0] * 100).ToString("F2") + "%)"; - // update the I/O graph - long ioR = _deltaManager.GetDelta("io_r"); - long ioW = _deltaManager.GetDelta("io_w"); - long ioO = _deltaManager.GetDelta("io_o"); - plotterIO.Add(ioR + ioO, ioW); - plotterIO.Text = "R+O: " + Misc.GetNiceSizeName(ioR + ioO) + - ", W: " + Misc.GetNiceSizeName(ioW); + // update the I/O graph text + plotterIO.Text = "R+O: " + Misc.GetNiceSizeName(plotterIO.LongData1[0]) + + ", W: " + Misc.GetNiceSizeName(plotterIO.LongData2[0]); - // update the memory graph - long commitSize = perfInfo.CommittedPages * _pageSize; - long physMemoryUsage = (_pages - perfInfo.AvailablePages) * _pageSize; - plotterMemory.Add(commitSize, physMemoryUsage); - plotterMemory.Text = "Commit: " + Misc.GetNiceSizeName(commitSize) + - ", Phys. Mem: " + Misc.GetNiceSizeName(physMemoryUsage); + // update the memory graph text + plotterMemory.Text = "Commit: " + Misc.GetNiceSizeName(plotterMemory.LongData1[0]) + + ", Phys. Mem: " + Misc.GetNiceSizeName(plotterMemory.LongData2[0]); - _runCount++; + plotterCPU.MoveGrid(); + plotterCPU.Draw(); + plotterIO.MoveGrid(); + plotterIO.Draw(); + plotterMemory.MoveGrid(); + plotterMemory.Draw(); } private void UpdateInfo() @@ -265,7 +214,6 @@ namespace ProcessHacker { this.BeginInvoke(new MethodInvoker(delegate { - this.UpdateDeltas(); this.UpdateGraphs(); this.UpdateInfo(); })); diff --git a/trunk/ProcessHacker/HistoryManager.cs b/trunk/ProcessHacker/HistoryManager.cs new file mode 100644 index 000000000..b0a7a2b87 --- /dev/null +++ b/trunk/ProcessHacker/HistoryManager.cs @@ -0,0 +1,64 @@ +/* + * Process Hacker - + * history manager + * + * Copyright (C) 2009 wj32 + * + * This file is part of Process Hacker. + * + * Process Hacker is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Process Hacker is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Process Hacker. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text; + +namespace ProcessHacker +{ + public class HistoryManager + { + private Dictionary> _history = new Dictionary>(); + private int _maxCount = 400; + + public int MaxCount + { + get { return _maxCount; } + set { _maxCount = value; } + } + + public ReadOnlyCollection this[TKey key] + { + get { return GetHistory(key); } + } + + public void Add(TKey key) + { + _history.Add(key, new List()); + } + + public ReadOnlyCollection GetHistory(TKey key) + { + return new ReadOnlyCollection(_history[key]); + } + + public void Update(TKey key, TValue value) + { + _history[key].Insert(0, value); + + if (_history[key].Count > _maxCount) + _history[key].RemoveRange(_history[key].Count - 1, _history[key].Count - _maxCount); + } + } +} diff --git a/trunk/ProcessHacker/ProcessHacker.csproj b/trunk/ProcessHacker/ProcessHacker.csproj index f7cbd585c..587d79ad6 100644 --- a/trunk/ProcessHacker/ProcessHacker.csproj +++ b/trunk/ProcessHacker/ProcessHacker.csproj @@ -545,6 +545,7 @@ VirtualProtectWindow.cs + diff --git a/trunk/ProcessHacker/Properties/Settings.Designer.cs b/trunk/ProcessHacker/Properties/Settings.Designer.cs index 7413a00ec..db36a1552 100644 --- a/trunk/ProcessHacker/Properties/Settings.Designer.cs +++ b/trunk/ProcessHacker/Properties/Settings.Designer.cs @@ -1128,5 +1128,29 @@ namespace ProcessHacker.Properties { this["ToolbarVisible"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("858, 545")] + public global::System.Drawing.Size SysInfoWindowSize { + get { + return ((global::System.Drawing.Size)(this["SysInfoWindowSize"])); + } + set { + this["SysInfoWindowSize"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("100, 100")] + public global::System.Drawing.Point SysInfoWindowLocation { + get { + return ((global::System.Drawing.Point)(this["SysInfoWindowLocation"])); + } + set { + this["SysInfoWindowLocation"] = value; + } + } } } diff --git a/trunk/ProcessHacker/Properties/Settings.settings b/trunk/ProcessHacker/Properties/Settings.settings index 631996311..e383a6383 100644 --- a/trunk/ProcessHacker/Properties/Settings.settings +++ b/trunk/ProcessHacker/Properties/Settings.settings @@ -278,5 +278,11 @@ False + + 858, 545 + + + 100, 100 + \ No newline at end of file diff --git a/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs b/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs index da85174ce..0bb3ca614 100644 --- a/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs +++ b/trunk/ProcessHacker/Providers/ProcessSystemProvider.cs @@ -27,16 +27,22 @@ using System.Drawing; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Threading; +using System.Collections.ObjectModel; namespace ProcessHacker { + public enum ProcessStats + { + CpuKernel, CpuUser, IoRead, IoWrite, IoOther, IoReadOther, PrivateMemory, WorkingSet + } + public struct ProcessItem { public int PID; public Icon Icon; public string CmdLine; - public float CPUUsage; + public float CpuUsage; public string FileName; public FileVersionInfo VersionInfo; public string Name; @@ -50,10 +56,9 @@ namespace ProcessHacker public bool IsElevated; public bool IsInJob; public bool IsPacked; - public long LastTime; public int SessionId; public bool HasParent; - public int ParentPID; + public int ParentPid; public Win32.VerifyResult VerifyResult; public int ImportFunctions; @@ -65,6 +70,14 @@ namespace ProcessHacker public Win32.ProcessHandle ProcessQueryHandle; public bool FullUpdate; + public DeltaManager DeltaManager; + public HistoryManager FloatHistoryManager; + public HistoryManager LongHistoryManager; + } + + public enum SystemStats + { + CpuKernel, CpuUser, CpuOther, IoRead, IoWrite, IoOther, IoReadOther, Commit, PhysicalMemory } public class ProcessSystemProvider : Provider @@ -81,9 +94,11 @@ namespace ProcessHacker private Dictionary _fileResults = new Dictionary(); private Queue _fpResults = new Queue(); - private long _lastOtherTime; - private long _lastSysKernelTime; - private long _lastSysUserTime; + private DeltaManager _longDeltas = new DeltaManager(new Int64Subtractor()); + private DeltaManager _cpuDeltas = new DeltaManager(new Int64Subtractor()); + private HistoryManager _longHistory = new HistoryManager(); + private HistoryManager _floatHistory = new HistoryManager(); + private HistoryManager _mostUsageHistory = new HistoryManager(); private delegate void ProcessFileDelegate(int pid, string fileName); @@ -101,20 +116,58 @@ namespace ProcessHacker this.ProcessorPerfArray = new Win32.SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[this.System.NumberOfProcessors]; this.UpdateProcessorPerf(); - _lastSysKernelTime = this.ProcessorPerf.KernelTime; - _lastSysUserTime = this.ProcessorPerf.UserTime; - _lastOtherTime = this.ProcessorPerf.IdleTime + this.ProcessorPerf.DpcTime + - this.ProcessorPerf.InterruptTime; + + _mostUsageHistory = new HistoryManager(); + _mostUsageHistory.Add(false); + _mostUsageHistory.Add(true); + + _longDeltas.Add(SystemStats.CpuKernel, this.ProcessorPerf.KernelTime); + _longDeltas.Add(SystemStats.CpuUser, this.ProcessorPerf.UserTime); + _longDeltas.Add(SystemStats.CpuOther, + this.ProcessorPerf.IdleTime + this.ProcessorPerf.DpcTime + this.ProcessorPerf.InterruptTime); + _longDeltas.Add(SystemStats.IoRead, this.Performance.IoReadTransferCount); + _longDeltas.Add(SystemStats.IoWrite, this.Performance.IoWriteTransferCount); + _longDeltas.Add(SystemStats.IoOther, this.Performance.IoOtherTransferCount); + + _floatHistory.Add("Kernel"); + _floatHistory.Add("User"); + _floatHistory.Add("Other"); + + for (int i = 0; i < this.System.NumberOfProcessors; i++) + { + _cpuDeltas.Add(i.ToString() + " Kernel", this.ProcessorPerfArray[i].KernelTime); + _cpuDeltas.Add(i.ToString() + " User", this.ProcessorPerfArray[i].UserTime); + _cpuDeltas.Add(i.ToString() + " Other", + this.ProcessorPerfArray[i].IdleTime + this.ProcessorPerfArray[i].DpcTime + + this.ProcessorPerfArray[i].InterruptTime); + _floatHistory.Add(i.ToString() + " Kernel"); + _floatHistory.Add(i.ToString() + " User"); + _floatHistory.Add(i.ToString() + " Other"); + } + + _longHistory.Add(SystemStats.IoRead); + _longHistory.Add(SystemStats.IoWrite); + _longHistory.Add(SystemStats.IoOther); + _longHistory.Add(SystemStats.IoReadOther); + _longHistory.Add(SystemStats.Commit); + _longHistory.Add(SystemStats.PhysicalMemory); } public Win32.SYSTEM_BASIC_INFORMATION System { get; private set; } public Win32.SYSTEM_PERFORMANCE_INFORMATION Performance { get; private set; } public Win32.SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION ProcessorPerf { get; private set; } public Win32.SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[] ProcessorPerfArray { get; private set; } - public float CurrentCPUKernelUsage { get; private set; } - public float CurrentCPUUserUsage { get; private set; } - public float CurrentCPUUsage { get { return this.CurrentCPUKernelUsage + this.CurrentCPUUserUsage; } } - public int PIDWithMostCPUUsage { get; private set; } + public float CurrentCpuKernelUsage { get; private set; } + public float CurrentCpuUserUsage { get; private set; } + public float CurrentCpuUsage { get { return this.CurrentCpuKernelUsage + this.CurrentCpuUserUsage; } } + public int PIDWithMostIoActivity { get; private set; } + public int PIDWithMostCpuUsage { get; private set; } + public DeltaManager CpuDeltas { get { return _cpuDeltas; } } + public DeltaManager LongDeltas { get { return _longDeltas; } } + public HistoryManager FloatHistory { get { return _floatHistory; } } + public HistoryManager LongHistory { get { return _longHistory; } } + public ReadOnlyCollection MostCpuHistory { get { return _mostUsageHistory[false]; } } + public ReadOnlyCollection MostIoHistory { get { return _mostUsageHistory[true]; } } public Queue FileProcessingQueue { @@ -313,17 +366,60 @@ namespace ProcessHacker Dictionary newdictionary = new Dictionary(this.Dictionary); Win32.WtsEnumProcessesFastData wtsEnumData = new Win32.WtsEnumProcessesFastData(); - long thisSysKernelTime = this.ProcessorPerf.KernelTime; - long sysKernelTime = thisSysKernelTime - _lastSysKernelTime; - _lastSysKernelTime = thisSysKernelTime; + _longDeltas.Update(SystemStats.CpuKernel, this.ProcessorPerf.KernelTime); + long sysKernelTime = _longDeltas[SystemStats.CpuKernel]; - long thisSysUserTime = this.ProcessorPerf.UserTime; - long sysUserTime = thisSysUserTime - _lastSysUserTime; - _lastSysUserTime = thisSysUserTime; + _longDeltas.Update(SystemStats.CpuUser, this.ProcessorPerf.UserTime); + long sysUserTime = _longDeltas[SystemStats.CpuUser]; - long thisOtherTime = this.ProcessorPerf.IdleTime + this.ProcessorPerf.DpcTime + this.ProcessorPerf.InterruptTime; - long otherTime = thisOtherTime - _lastOtherTime; - _lastOtherTime = thisOtherTime; + _longDeltas.Update(SystemStats.CpuOther, + this.ProcessorPerf.IdleTime + this.ProcessorPerf.DpcTime + this.ProcessorPerf.InterruptTime); + long otherTime = _longDeltas[SystemStats.CpuOther]; + + _longDeltas.Update(SystemStats.IoRead, this.Performance.IoReadTransferCount); + _longDeltas.Update(SystemStats.IoWrite, this.Performance.IoWriteTransferCount); + _longDeltas.Update(SystemStats.IoOther, this.Performance.IoOtherTransferCount); + + if (this.ProcessorPerf.KernelTime != 0 && this.ProcessorPerf.UserTime != 0) + { + this.CurrentCpuKernelUsage = (float)sysKernelTime / (sysKernelTime + sysUserTime + otherTime); + this.CurrentCpuUserUsage = (float)sysUserTime / (sysKernelTime + sysUserTime + otherTime); + + _floatHistory.Update("Kernel", this.CurrentCpuKernelUsage); + _floatHistory.Update("User", this.CurrentCpuUserUsage); + _floatHistory.Update("Other", (float)otherTime / (sysKernelTime + sysUserTime + otherTime)); + } + + for (int i = 0; i < this.System.NumberOfProcessors; i++) + { + long cpuKernelTime = _cpuDeltas.Update(i.ToString() + " Kernel", this.ProcessorPerfArray[i].KernelTime); + long cpuUserTime = _cpuDeltas.Update(i.ToString() + " User", this.ProcessorPerfArray[i].UserTime); + long cpuOtherTime = _cpuDeltas.Update(i.ToString() + " Other", + this.ProcessorPerfArray[i].IdleTime + this.ProcessorPerfArray[i].DpcTime + + this.ProcessorPerfArray[i].InterruptTime); + _floatHistory.Update(i.ToString() + " Kernel", + (float)cpuKernelTime / (cpuKernelTime + cpuUserTime + cpuOtherTime)); + _floatHistory.Update(i.ToString() + " User", + (float)cpuUserTime / (cpuKernelTime + cpuUserTime + cpuOtherTime)); + _floatHistory.Update(i.ToString() + " Other", + (float)cpuOtherTime / (cpuKernelTime + cpuUserTime + cpuOtherTime)); + } + + if (this.RunCount < 3) + { + _longDeltas[SystemStats.IoRead] = 0; + _longDeltas[SystemStats.IoWrite] = 0; + _longDeltas[SystemStats.IoOther] = 0; + } + + _longHistory.Update(SystemStats.IoRead, _longDeltas[SystemStats.IoRead]); + _longHistory.Update(SystemStats.IoWrite, _longDeltas[SystemStats.IoWrite]); + _longHistory.Update(SystemStats.IoOther, _longDeltas[SystemStats.IoOther]); + _longHistory.Update(SystemStats.IoReadOther, + _longDeltas[SystemStats.IoRead] + _longDeltas[SystemStats.IoOther]); + _longHistory.Update(SystemStats.Commit, this.Performance.CommittedPages * this.System.PageSize); + _longHistory.Update(SystemStats.PhysicalMemory, + (this.System.NumberOfPhysicalPages - this.Performance.AvailablePages) * this.System.PageSize); // set System Idle Process CPU time if (procs.ContainsKey(0)) @@ -360,6 +456,7 @@ namespace ProcessHacker }); float mostCPUUsage = 0; + long mostIOActivity = 0; // look for dead processes foreach (int pid in Dictionary.Keys) @@ -426,7 +523,6 @@ namespace ProcessHacker } item.PID = pid; - item.LastTime = processInfo.KernelTime + processInfo.UserTime; item.Process = processInfo; item.SessionId = processInfo.SessionId; item.Threads = procs[pid].Threads; @@ -434,6 +530,23 @@ namespace ProcessHacker item.Name = procs[pid].Name; + item.DeltaManager = new DeltaManager(new Int64Subtractor()); + item.DeltaManager.Add(ProcessStats.CpuKernel, processInfo.KernelTime); + item.DeltaManager.Add(ProcessStats.CpuUser, processInfo.UserTime); + item.DeltaManager.Add(ProcessStats.IoRead, (long)processInfo.IoCounters.ReadTransferCount); + item.DeltaManager.Add(ProcessStats.IoWrite, (long)processInfo.IoCounters.WriteTransferCount); + item.DeltaManager.Add(ProcessStats.IoOther, (long)processInfo.IoCounters.OtherTransferCount); + item.FloatHistoryManager = new HistoryManager(); + item.LongHistoryManager = new HistoryManager(); + item.FloatHistoryManager.Add(ProcessStats.CpuKernel); + item.FloatHistoryManager.Add(ProcessStats.CpuUser); + item.LongHistoryManager.Add(ProcessStats.IoReadOther); + item.LongHistoryManager.Add(ProcessStats.IoRead); + item.LongHistoryManager.Add(ProcessStats.IoWrite); + item.LongHistoryManager.Add(ProcessStats.IoOther); + item.LongHistoryManager.Add(ProcessStats.PrivateMemory); + item.LongHistoryManager.Add(ProcessStats.WorkingSet); + // HACK: Shouldn't happen, but it does. if (item.Name == null) { @@ -449,17 +562,17 @@ namespace ProcessHacker if (pid > 0) { - item.ParentPID = processInfo.InheritedFromProcessId; + item.ParentPid = processInfo.InheritedFromProcessId; item.HasParent = true; - if (!procs.ContainsKey(item.ParentPID)) + if (!procs.ContainsKey(item.ParentPid)) { item.HasParent = false; } - else if (procs.ContainsKey(item.ParentPID)) + else if (procs.ContainsKey(item.ParentPid)) { // check the parent's creation time to see if it's actually the parent - long parentStartTime = procs[item.ParentPID].Process.CreateTime; + long parentStartTime = procs[item.ParentPid].Process.CreateTime; long thisStartTime = processInfo.CreateTime; if (parentStartTime > thisStartTime) @@ -570,12 +683,12 @@ namespace ProcessHacker } else if (pid == -2) { - item.ParentPID = 0; + item.ParentPid = 0; item.HasParent = true; } else if (pid == -3) { - item.ParentPID = 0; + item.ParentPid = 0; item.HasParent = true; } else @@ -640,7 +753,26 @@ namespace ProcessHacker ProcessItem item = Dictionary[pid]; ProcessItem newitem = item; - newitem.LastTime = processInfo.KernelTime + processInfo.UserTime; + newitem.DeltaManager.Update(ProcessStats.CpuKernel, processInfo.KernelTime); + newitem.DeltaManager.Update(ProcessStats.CpuUser, processInfo.UserTime); + newitem.DeltaManager.Update(ProcessStats.IoRead, (long)processInfo.IoCounters.ReadTransferCount); + newitem.DeltaManager.Update(ProcessStats.IoWrite, (long)processInfo.IoCounters.WriteTransferCount); + newitem.DeltaManager.Update(ProcessStats.IoOther, (long)processInfo.IoCounters.OtherTransferCount); + + newitem.FloatHistoryManager.Update(ProcessStats.CpuKernel, + (float)newitem.DeltaManager[ProcessStats.CpuKernel] / + (sysKernelTime + sysUserTime + otherTime)); + newitem.FloatHistoryManager.Update(ProcessStats.CpuUser, + (float)newitem.DeltaManager[ProcessStats.CpuUser] / + (sysKernelTime + sysUserTime + otherTime)); + newitem.LongHistoryManager.Update(ProcessStats.IoRead, newitem.DeltaManager[ProcessStats.IoRead]); + newitem.LongHistoryManager.Update(ProcessStats.IoWrite, newitem.DeltaManager[ProcessStats.IoWrite]); + newitem.LongHistoryManager.Update(ProcessStats.IoOther, newitem.DeltaManager[ProcessStats.IoOther]); + newitem.LongHistoryManager.Update(ProcessStats.IoReadOther, + newitem.DeltaManager[ProcessStats.IoRead] + newitem.DeltaManager[ProcessStats.IoOther]); + newitem.LongHistoryManager.Update(ProcessStats.PrivateMemory, processInfo.VirtualMemoryCounters.PrivateBytes); + newitem.LongHistoryManager.Update(ProcessStats.WorkingSet, processInfo.VirtualMemoryCounters.VirtualSize); + newitem.Process = processInfo; newitem.FullUpdate = false; newitem.JustProcessed = false; @@ -650,20 +782,30 @@ namespace ProcessHacker try { - newitem.CPUUsage = (float)(newitem.LastTime - item.LastTime) * 100 / + newitem.CpuUsage = (float) + (newitem.DeltaManager[ProcessStats.CpuUser] + + newitem.DeltaManager[ProcessStats.CpuKernel]) * 100 / (sysKernelTime + sysUserTime + otherTime); - if (newitem.CPUUsage > 400.0f) - newitem.CPUUsage /= 8.0f; - else if (newitem.CPUUsage > 200.0f) - newitem.CPUUsage /= 4.0f; - else if (newitem.CPUUsage > 100.0f) - newitem.CPUUsage /= 2.0f; + if (newitem.CpuUsage > 400.0f) + newitem.CpuUsage /= 8.0f; + else if (newitem.CpuUsage > 200.0f) + newitem.CpuUsage /= 4.0f; + else if (newitem.CpuUsage > 100.0f) + newitem.CpuUsage /= 2.0f; - if (pid != 0 && newitem.CPUUsage > mostCPUUsage) + if (pid != 0 && newitem.CpuUsage > mostCPUUsage) { - mostCPUUsage = newitem.CPUUsage; - this.PIDWithMostCPUUsage = pid; + mostCPUUsage = newitem.CpuUsage; + this.PIDWithMostCpuUsage = pid; + } + + if (pid != 0 && (newitem.LongHistoryManager[ProcessStats.IoReadOther][0] + + newitem.LongHistoryManager[ProcessStats.IoWrite][0]) > mostIOActivity) + { + mostIOActivity = newitem.LongHistoryManager[ProcessStats.IoReadOther][0] + + newitem.LongHistoryManager[ProcessStats.IoWrite][0]; + this.PIDWithMostIoActivity = pid; } } catch @@ -695,10 +837,27 @@ namespace ProcessHacker } } - if (thisSysKernelTime != 0 && thisSysUserTime != 0) + try { - this.CurrentCPUKernelUsage = (float)sysKernelTime / (sysKernelTime + sysUserTime + otherTime); - this.CurrentCPUUserUsage = (float)sysUserTime / (sysKernelTime + sysUserTime + otherTime); + _mostUsageHistory.Update(false, newdictionary[this.PIDWithMostCpuUsage].Name + ": " + + newdictionary[this.PIDWithMostCpuUsage].CpuUsage.ToString("N2") + "%"); + } + catch + { + _mostUsageHistory.Update(false, ""); + } + + try + { + _mostUsageHistory.Update(true, newdictionary[this.PIDWithMostIoActivity].Name + ": " + + "R+O: " + Misc.GetNiceSizeName( + newdictionary[this.PIDWithMostIoActivity].LongHistoryManager[ProcessStats.IoReadOther][0]) + + ", W: " + Misc.GetNiceSizeName( + newdictionary[this.PIDWithMostIoActivity].LongHistoryManager[ProcessStats.IoWrite][0])); + } + catch + { + _mostUsageHistory.Update(true, ""); } Dictionary = newdictionary; diff --git a/trunk/ProcessHacker/UsageIcon.cs b/trunk/ProcessHacker/UsageIcon.cs index 6f56d6351..9d9b0abb6 100644 --- a/trunk/ProcessHacker/UsageIcon.cs +++ b/trunk/ProcessHacker/UsageIcon.cs @@ -2,7 +2,7 @@ * Process Hacker - * CPU usage icon drawing code * - * Copyright (C) 2008 wj32 + * Copyright (C) 2008-2009 wj32 * * This file is part of Process Hacker. * @@ -36,12 +36,16 @@ namespace ProcessHacker { public class UsageIcon { + private HistoryManager _history = new HistoryManager(); private Plotter _plotter; private int _width; private int _height; public UsageIcon(int width, int height) { + _history.Add(true); + _history.Add(false); + _width = width; _height = height; _plotter = new Plotter() @@ -50,13 +54,16 @@ namespace ProcessHacker UseSecondLine = true, ShowGrid = false, BackColor = Color.Black, - MoveStep = 2 + MoveStep = 2, + Data1 = _history[true], + Data2 = _history[false] }; } public void Update(float k, float u) { - _plotter.Add(k, u); + _history.Update(true, k); + _history.Update(false, u); } public Color BackColor { get; set; } @@ -70,6 +77,7 @@ namespace ProcessHacker using (Bitmap bm = new Bitmap(_width, _height)) { + _plotter.Draw(); _plotter.DrawToBitmap(bm, new Rectangle(new Point(0, 0), bm.Size)); return Icon.FromHandle(bm.GetHicon()); diff --git a/trunk/ProcessHacker/app.config b/trunk/ProcessHacker/app.config index e56008995..e7fe54a64 100644 --- a/trunk/ProcessHacker/app.config +++ b/trunk/ProcessHacker/app.config @@ -283,6 +283,12 @@ False + + 858, 545 + + + 100, 100 + \ No newline at end of file