Add implementation

This commit is contained in:
2014-05-02 16:55:59 -04:00
parent 9c7809dc86
commit 35b8971f10
11 changed files with 521 additions and 64 deletions

View File

@@ -1,6 +1,24 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<configuration> <configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="ProcessCpuUsageStatusWindow.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup> </startup>
<userSettings>
<ProcessCpuUsageStatusWindow.Properties.Settings>
<setting name="ProcessCount" serializeAs="String">
<value>3</value>
</setting>
<setting name="UpdateInterval" serializeAs="String">
<value>00:00:02</value>
</setting>
<setting name="WindowSettings" serializeAs="String">
<value />
</setting>
</ProcessCpuUsageStatusWindow.Properties.Settings>
</userSettings>
</configuration> </configuration>

View File

@@ -1,17 +1,23 @@
using System; using System.Windows;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace ProcessCpuUsageStatusWindow namespace ProcessCpuUsageStatusWindow
{ {
/// <summary> public partial class App
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{ {
private WindowSource _windowSource;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
_windowSource = new WindowSource();
}
protected override void OnExit(ExitEventArgs e)
{
_windowSource.Dispose();
base.OnExit(e);
}
} }
} }

60
ProcessCpuUsage.cs Normal file
View File

@@ -0,0 +1,60 @@
using System;
using System.Diagnostics;
namespace ProcessCpuUsageStatusWindow
{
public class ProcessCpuUsage
{
#region Properties
public string ProcessName { get; private set; }
public float PercentUsage { get; internal set; }
public DateTime LastFound { get; set; }
public bool UsageValid { get; private set; }
internal CounterSample LastSample { get; set; }
#endregion
#region Constructor
internal ProcessCpuUsage(InstanceData instanceData)
: this(instanceData, DateTime.MinValue)
{ }
internal ProcessCpuUsage(InstanceData instanceData, DateTime timestamp)
{
// Store the process details
ProcessName = instanceData.InstanceName;
// Store the initial data
LastFound = timestamp;
LastSample = instanceData.Sample;
// We start out as not valid
UsageValid = false;
}
#endregion
#region Usage update
internal void UpdateCpuUsage(InstanceData instanceData, DateTime timestamp)
{
// Get the new sample
var newSample = instanceData.Sample;
// Calculate percent usage
PercentUsage = CounterSample.Calculate(LastSample, newSample) / Environment.ProcessorCount;
// Update the last sample and timestmap
LastSample = newSample;
LastFound = timestamp;
// Usage is now valid
UsageValid = true;
}
#endregion
}
}

View File

@@ -34,13 +34,13 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="FloatingStatusWindowLibrary">
<HintPath>..\FloatingStatusWindowLibrary\FloatingStatusWindowLibrary\bin\Debug\FloatingStatusWindowLibrary.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Data" /> <Reference Include="System.Drawing" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Xaml"> <Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework> <RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference> </Reference>
@@ -57,8 +57,11 @@
<DependentUpon>App.xaml</DependentUpon> <DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="WindowSource.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="ProcessCpuUsage.cs" />
<Compile Include="ProcessCpuUsageWatcher.cs" />
<Compile Include="Properties\AssemblyInfo.cs"> <Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
@@ -85,6 +88,9 @@
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="Resources\ApplicationIcon.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

157
ProcessCpuUsageWatcher.cs Normal file
View File

@@ -0,0 +1,157 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Timers;
using System.Windows.Threading;
namespace ProcessCpuUsageStatusWindow
{
public class ProcessCpuUsageWatcher
{
#region Update delegate
public delegate void ProcessListUpdatedDelegate(Dictionary<string, ProcessCpuUsage> currentProcessList);
#endregion
#region Member variables
private Dispatcher _dispatcher;
private Timer _processUpdateTimer;
private ProcessListUpdatedDelegate _processListUpdatedCallback;
private PerformanceCounterCategory _processCategory;
#endregion
#region Properties
public Dictionary<string, ProcessCpuUsage> CurrentProcessList;
#endregion
#region Initialize and terminate
public void Initialize(TimeSpan updateInterval, ProcessListUpdatedDelegate callback)
{
_dispatcher = Dispatcher.CurrentDispatcher;
// Create a new dictionary for the process list
CurrentProcessList = new Dictionary<string, ProcessCpuUsage>();
// Get the category for process performance info
_processCategory = PerformanceCounterCategory.GetCategories().FirstOrDefault(category => category.CategoryName == "Process");
if (_processCategory == null)
return;
// Read the entire category
InstanceDataCollectionCollection processCategoryData = _processCategory.ReadCategory();
// Get the processor time data
InstanceDataCollection processorTimeData = processCategoryData["% processor time"];
if (processorTimeData == null || processorTimeData.Values == null)
return;
// Loop over each instance and add it to the list
foreach (InstanceData instanceData in processorTimeData.Values)
{
// Create a new process usage object
var processCpuUsage = new ProcessCpuUsage(instanceData);
// Add to the list
CurrentProcessList.Add(processCpuUsage.ProcessName, processCpuUsage);
}
// Save the update callback
_processListUpdatedCallback = callback;
// Create a timer to update the process list
_processUpdateTimer = new Timer(updateInterval.TotalMilliseconds) { AutoReset = false };
_processUpdateTimer.Elapsed += HandleProcessUpdateTimerElapsed;
_processUpdateTimer.Start();
}
public void Terminate()
{
// Get rid of the timer
_processUpdateTimer.Stop();
_processUpdateTimer.Dispose();
// Clear the callback
_processListUpdatedCallback = null;
// Clear the process list
CurrentProcessList = null;
}
#endregion
#region Timer handling
private void HandleProcessUpdateTimerElapsed(object sender, ElapsedEventArgs e)
{
// Update the current process list
UpdateCurrentProcessList();
// Restart the timer
_processUpdateTimer.Start();
}
#endregion
#region Process list management
private void UpdateCurrentProcessList()
{
// Get a timestamp for the current time that we can use to see if a process was found this check
DateTime checkStart = DateTime.Now;
// Read the entire category
InstanceDataCollectionCollection processCategoryData = _processCategory.ReadCategory();
// Get the processor time data
InstanceDataCollection processorTimeData = processCategoryData["% processor time"];
if (processorTimeData == null || processorTimeData.Values == null)
return;
// Loop over each instance and add it to the list
foreach (InstanceData instanceData in processorTimeData.Values)
{
// See if we already know about this process
if (CurrentProcessList.ContainsKey(instanceData.InstanceName))
{
// Get the previous process usage object
ProcessCpuUsage processCpuUsage = CurrentProcessList[instanceData.InstanceName];
// Update the CPU usage with new data
processCpuUsage.UpdateCpuUsage(instanceData, checkStart);
}
else
{
// Create a new CPU usage object
var processCpuUsage = new ProcessCpuUsage(instanceData, checkStart);
// Add it to the list
CurrentProcessList.Add(processCpuUsage.ProcessName, processCpuUsage);
}
}
// Build a list of cached processes we haven't found this check
var oldProcessList = (from processCpuUsage in CurrentProcessList
where processCpuUsage.Value.LastFound != checkStart
select processCpuUsage.Key).ToList();
// Loop over the list and remove the old process
foreach (var key in oldProcessList)
CurrentProcessList.Remove(key);
// Invoke the callback with the new current process list
_dispatcher.InvokeAsync(() => _processListUpdatedCallback.Invoke(CurrentProcessList));
}
#endregion
}
}

View File

@@ -8,8 +8,8 @@
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace ProcessCpuUsageStatusWindow.Properties namespace ProcessCpuUsageStatusWindow.Properties {
{ using System;
/// <summary> /// <summary>
@@ -22,28 +22,23 @@ namespace ProcessCpuUsageStatusWindow.Properties
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources internal class Resources {
{
private static global::System.Resources.ResourceManager resourceMan; private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture; private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() internal Resources() {
{
} }
/// <summary> /// <summary>
/// Returns the cached ResourceManager instance used by this class. /// Returns the cached ResourceManager instance used by this class.
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager internal static global::System.Resources.ResourceManager ResourceManager {
{ get {
get if (object.ReferenceEquals(resourceMan, null)) {
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ProcessCpuUsageStatusWindow.Properties.Resources", typeof(Resources).Assembly); global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ProcessCpuUsageStatusWindow.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp; resourceMan = temp;
} }
@@ -56,16 +51,59 @@ namespace ProcessCpuUsageStatusWindow.Properties
/// resource lookups using this strongly typed resource class. /// resource lookups using this strongly typed resource class.
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture internal static global::System.Globalization.CultureInfo Culture {
{ get {
get
{
return resourceCulture; return resourceCulture;
} }
set set {
{
resourceCulture = value; resourceCulture = value;
} }
} }
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>
internal static System.Drawing.Icon ApplicationIcon {
get {
object obj = ResourceManager.GetObject("ApplicationIcon", resourceCulture);
return ((System.Drawing.Icon)(obj));
}
}
/// <summary>
/// Looks up a localized string similar to CPU: {0,4:f1}% - Total.
/// </summary>
internal static string FooterLine {
get {
return ResourceManager.GetString("FooterLine", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to .
/// </summary>
internal static string HeaderLine {
get {
return ResourceManager.GetString("HeaderLine", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Loading....
/// </summary>
internal static string Loading {
get {
return ResourceManager.GetString("Loading", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to CPU: {1,4:f1}% - {0}.
/// </summary>
internal static string ProcessLine {
get {
return ResourceManager.GetString("ProcessLine", resourceCulture);
}
}
} }
} }

View File

@@ -46,7 +46,7 @@
mimetype: application/x-microsoft.net.object.binary.base64 mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 mimetype: application/x-microsoft.net.object.soap.base64
@@ -60,6 +60,7 @@
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true"> <xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType> <xsd:complexType>
<xsd:choice maxOccurs="unbounded"> <xsd:choice maxOccurs="unbounded">
@@ -68,9 +69,10 @@
<xsd:sequence> <xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" /> <xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" /> <xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" /> <xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" /> <xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="assembly"> <xsd:element name="assembly">
@@ -85,9 +87,10 @@
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence> </xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" /> <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType> </xsd:complexType>
</xsd:element> </xsd:element>
<xsd:element name="resheader"> <xsd:element name="resheader">
@@ -109,9 +112,25 @@
<value>2.0</value> <value>2.0</value>
</resheader> </resheader>
<resheader name="reader"> <resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="ApplicationIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ApplicationIcon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="FooterLine" xml:space="preserve">
<value>CPU: {0,4:f1}% - Total</value>
</data>
<data name="HeaderLine" xml:space="preserve">
<value />
</data>
<data name="Loading" xml:space="preserve">
<value>Loading...</value>
</data>
<data name="ProcessLine" xml:space="preserve">
<value>CPU: {1,4:f1}% - {0}</value>
</data>
</root> </root>

View File

@@ -8,23 +8,55 @@
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace ProcessCpuUsageStatusWindow.Properties namespace ProcessCpuUsageStatusWindow.Properties {
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
{
private static Settings defaultInstance = ((Settings) (global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default public static Settings Default {
{ get {
get
{
return defaultInstance; return defaultInstance;
} }
} }
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3")]
public int ProcessCount {
get {
return ((int)(this["ProcessCount"]));
}
set {
this["ProcessCount"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("00:00:02")]
public global::System.TimeSpan UpdateInterval {
get {
return ((global::System.TimeSpan)(this["UpdateInterval"]));
}
set {
this["UpdateInterval"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string WindowSettings {
get {
return ((string)(this["WindowSettings"]));
}
set {
this["WindowSettings"] = value;
}
}
} }
} }

View File

@@ -1,7 +1,15 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)"> <SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="ProcessCpuUsageStatusWindow.Properties" GeneratedClassName="Settings">
<Profiles> <Profiles />
<Profile Name="(Default)" /> <Settings>
</Profiles> <Setting Name="ProcessCount" Type="System.Int32" Scope="User">
<Settings /> <Value Profile="(Default)">3</Value>
</Setting>
<Setting Name="UpdateInterval" Type="System.TimeSpan" Scope="User">
<Value Profile="(Default)">00:00:02</Value>
</Setting>
<Setting Name="WindowSettings" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile> </SettingsFile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

113
WindowSource.cs Normal file
View File

@@ -0,0 +1,113 @@
using FloatingStatusWindowLibrary;
using ProcessCpuUsageStatusWindow.Properties;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ProcessCpuUsageStatusWindow
{
public class WindowSource : IWindowSource, IDisposable
{
private readonly FloatingStatusWindow _floatingStatusWindow;
private readonly ProcessCpuUsageWatcher _processCpuUsageWatcher;
internal WindowSource()
{
_floatingStatusWindow = new FloatingStatusWindow(this);
_floatingStatusWindow.SetText(Resources.Loading);
_processCpuUsageWatcher = new ProcessCpuUsageWatcher();
_processCpuUsageWatcher.Initialize(Settings.Default.UpdateInterval, UpdateDisplay);
}
public void Dispose()
{
_processCpuUsageWatcher.Terminate();
_floatingStatusWindow.Save();
_floatingStatusWindow.Dispose();
}
public string Name
{
get { return "Process CPU Usage"; }
}
public System.Drawing.Icon Icon
{
get { return Resources.ApplicationIcon; }
}
public string WindowSettings
{
get
{
return Settings.Default.WindowSettings;
}
set
{
Settings.Default.WindowSettings = value;
Settings.Default.Save();
}
}
#region Display updating
private static class PredefinedProcessName
{
public const string Total = "_Total";
public const string Idle = "Idle";
}
private void UpdateDisplay(Dictionary<string, ProcessCpuUsage> currentProcessList)
{
// Filter the process list to valid ones and exclude the idle and total values
var validProcessList = (currentProcessList.Values.Where(
process =>
process.UsageValid && process.ProcessName != PredefinedProcessName.Total &&
process.ProcessName != PredefinedProcessName.Idle)).ToList();
// Calculate the total usage by adding up all the processes we know about
var totalUsage = validProcessList.Sum(process => process.PercentUsage);
// Sort the process list by usage and take only the top few
var sortedProcessList = (validProcessList.OrderByDescending(process => process.PercentUsage)).Take(Settings.Default.ProcessCount);
// Create a new string builder
var stringBuilder = new StringBuilder();
// Add the header line (if any)
if (Resources.HeaderLine.Length > 0)
{
stringBuilder.AppendFormat(Resources.HeaderLine, totalUsage);
stringBuilder.AppendLine();
stringBuilder.AppendLine();
}
// Loop over all processes in the sorted list
foreach (ProcessCpuUsage processCpuUsage in sortedProcessList)
{
// Move to the next line if it isn't the first line
if (stringBuilder.Length != 0)
stringBuilder.AppendLine();
// Format the process information into a string to display
stringBuilder.AppendFormat(Resources.ProcessLine, processCpuUsage.ProcessName, processCpuUsage.PercentUsage);
}
// Add the footer line (if any)
if (Resources.FooterLine.Length > 0)
{
stringBuilder.AppendLine();
stringBuilder.AppendLine();
stringBuilder.AppendFormat(Resources.FooterLine, totalUsage);
}
// Update the window with the text
_floatingStatusWindow.SetText(stringBuilder.ToString());
}
#endregion
}
}