Release version 0.1.13. Replaced PerformanceCounter based CPU load sensors with an implementation using NtQuerySystemInformation. Fixed a temperature reading problem for W83627DHG chips (sensors with invalid value 127?C).
authormoel.mich
Thu, 04 Feb 2010 21:19:27 +0000
changeset 260e01b63e1fdc
parent 25 ff3e6edc7113
child 27 beed5a9e1b78
Release version 0.1.13. Replaced PerformanceCounter based CPU load sensors with an implementation using NtQuerySystemInformation. Fixed a temperature reading problem for W83627DHG chips (sensors with invalid value 127?C).
Hardware/CPU/AMD0FCPU.cs
Hardware/CPU/AMD10CPU.cs
Hardware/CPU/CPULoad.cs
Hardware/CPU/IntelCPU.cs
Hardware/LPC/W83627DHG.cs
OpenHardwareMonitor.csproj
Properties/AssemblyInfo.cs
Resources/app.manifest
Utilities/HexStringArray.cs
     1.1 --- a/Hardware/CPU/AMD0FCPU.cs	Wed Feb 03 22:02:58 2010 +0000
     1.2 +++ b/Hardware/CPU/AMD0FCPU.cs	Thu Feb 04 21:19:27 2010 +0000
     1.3 @@ -58,8 +58,7 @@
     1.4  
     1.5      private List<ISensor> active = new List<ISensor>();
     1.6  
     1.7 -    private PerformanceCounter totalLoadCounter;
     1.8 -    private PerformanceCounter[] coreLoadCounters;
     1.9 +    private CPULoad cpuLoad;
    1.10  
    1.11      private const ushort PCI_AMD_VENDOR_ID = 0x1022;
    1.12      private const ushort PCI_AMD_0FH_MISCELLANEOUS_DEVICE_ID = 0x1103;
    1.13 @@ -80,37 +79,23 @@
    1.14        // max two cores
    1.15        coreCount = coreCount > 2 ? 2 : coreCount;
    1.16  
    1.17 -      try {
    1.18 -        totalLoadCounter = new PerformanceCounter();
    1.19 -        totalLoadCounter.CategoryName = "Processor";
    1.20 -        totalLoadCounter.CounterName = "% Processor Time";
    1.21 -        totalLoadCounter.InstanceName = "_Total";
    1.22 -        totalLoadCounter.NextValue();
    1.23 -      } catch (Exception) {
    1.24 -        totalLoadCounter = null;
    1.25 -      }
    1.26        totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
    1.27 -
    1.28 -      coreLoadCounters = new PerformanceCounter[coreCount];
    1.29 +        
    1.30 +      coreTemperatures = new Sensor[coreCount];
    1.31        coreLoads = new Sensor[coreCount];
    1.32 -      for (int i = 0; i < coreLoadCounters.Length; i++) {
    1.33 -        try {
    1.34 -          coreLoadCounters[i] = new PerformanceCounter();
    1.35 -          coreLoadCounters[i].CategoryName = "Processor";
    1.36 -          coreLoadCounters[i].CounterName = "% Processor Time";
    1.37 -          coreLoadCounters[i].InstanceName = i.ToString();
    1.38 -          coreLoadCounters[i].NextValue();
    1.39 -        } catch (Exception) {
    1.40 -          coreLoadCounters[i] = null;
    1.41 -        }
    1.42 +      for (int i = 0; i < coreCount; i++) {
    1.43 +        coreTemperatures[i] =
    1.44 +          new Sensor("Core #" + (i + 1), i, SensorType.Temperature, this);
    1.45          coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
    1.46            SensorType.Load, this);
    1.47 -      }        
    1.48 +      }
    1.49  
    1.50 -      coreTemperatures = new Sensor[coreCount];
    1.51 -      for (int i = 0; i < coreCount; i++)
    1.52 -        coreTemperatures[i] = 
    1.53 -          new Sensor("Core #" + (i + 1), i, SensorType.Temperature, this);
    1.54 +      cpuLoad = new CPULoad(coreCount, 1);
    1.55 +      if (cpuLoad.IsAvailable) {
    1.56 +        foreach (Sensor sensor in coreLoads)
    1.57 +          ActivateSensor(sensor);
    1.58 +        ActivateSensor(totalLoad);
    1.59 +      }
    1.60  
    1.61        pciAddress = WinRing0.FindPciDeviceById(PCI_AMD_VENDOR_ID,
    1.62          PCI_AMD_0FH_MISCELLANEOUS_DEVICE_ID, 0);
    1.63 @@ -163,16 +148,12 @@
    1.64          }
    1.65        }
    1.66  
    1.67 -      if (totalLoadCounter != null) {
    1.68 -        totalLoad.Value = totalLoadCounter.NextValue();
    1.69 -        ActivateSensor(totalLoad);
    1.70 +      if (cpuLoad.IsAvailable) {
    1.71 +        cpuLoad.Update();
    1.72 +        for (int i = 0; i < coreLoads.Length; i++)
    1.73 +          coreLoads[i].Value = cpuLoad.GetCoreLoad(i);
    1.74 +        totalLoad.Value = cpuLoad.GetTotalLoad();
    1.75        }
    1.76 -
    1.77 -      for (int i = 0; i < coreLoads.Length; i++)
    1.78 -        if (coreLoadCounters[i] != null) {
    1.79 -          coreLoads[i].Value = coreLoadCounters[i].NextValue();
    1.80 -          ActivateSensor(coreLoads[i]);
    1.81 -        }
    1.82      }
    1.83  
    1.84      private void ActivateSensor(Sensor sensor) {
     2.1 --- a/Hardware/CPU/AMD10CPU.cs	Wed Feb 03 22:02:58 2010 +0000
     2.2 +++ b/Hardware/CPU/AMD10CPU.cs	Thu Feb 04 21:19:27 2010 +0000
     2.3 @@ -55,8 +55,7 @@
     2.4  
     2.5      private List<ISensor> active = new List<ISensor>();
     2.6  
     2.7 -    private PerformanceCounter totalLoadCounter;
     2.8 -    private PerformanceCounter[] coreLoadCounters;
     2.9 +    private CPULoad cpuLoad;
    2.10  
    2.11      private const ushort PCI_AMD_VENDOR_ID = 0x1022;
    2.12      private const ushort PCI_AMD_10H_MISCELLANEOUS_DEVICE_ID = 0x1203;
    2.13 @@ -72,32 +71,19 @@
    2.14        if (cpuidExtData.GetLength(0) > 8)
    2.15          coreCount = (cpuidExtData[8, 2] & 0xFF) + 1;
    2.16  
    2.17 -      try {
    2.18 -        totalLoadCounter = new PerformanceCounter();
    2.19 -        totalLoadCounter.CategoryName = "Processor";
    2.20 -        totalLoadCounter.CounterName = "% Processor Time";
    2.21 -        totalLoadCounter.InstanceName = "_Total";
    2.22 -        totalLoadCounter.NextValue();
    2.23 -      } catch (Exception) {
    2.24 -        totalLoadCounter = null;
    2.25 -      }
    2.26        totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
    2.27  
    2.28 -      coreLoadCounters = new PerformanceCounter[coreCount];
    2.29        coreLoads = new Sensor[coreCount];
    2.30 -      for (int i = 0; i < coreLoadCounters.Length; i++) {
    2.31 -        try {
    2.32 -          coreLoadCounters[i] = new PerformanceCounter();
    2.33 -          coreLoadCounters[i].CategoryName = "Processor";
    2.34 -          coreLoadCounters[i].CounterName = "% Processor Time";
    2.35 -          coreLoadCounters[i].InstanceName = i.ToString();
    2.36 -          coreLoadCounters[i].NextValue();
    2.37 -        } catch (Exception) {
    2.38 -          coreLoadCounters[i] = null;
    2.39 -        }
    2.40 +      for (int i = 0; i < coreCount; i++) 
    2.41          coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
    2.42            SensorType.Load, this);
    2.43 -      }        
    2.44 +
    2.45 +      cpuLoad = new CPULoad(coreCount, 1);
    2.46 +      if (cpuLoad.IsAvailable) {
    2.47 +        foreach (Sensor sensor in coreLoads)
    2.48 +          ActivateSensor(sensor);
    2.49 +        ActivateSensor(totalLoad);
    2.50 +      }    
    2.51        
    2.52        // AMD family 10h processors support only one temperature sensor
    2.53        coreTemperature = new Sensor(
    2.54 @@ -142,16 +128,12 @@
    2.55          DeactivateSensor(coreTemperature);
    2.56        }
    2.57  
    2.58 -      if (totalLoadCounter != null) {
    2.59 -        totalLoad.Value = totalLoadCounter.NextValue();
    2.60 -        ActivateSensor(totalLoad);
    2.61 +      if (cpuLoad.IsAvailable) {
    2.62 +        cpuLoad.Update();
    2.63 +        for (int i = 0; i < coreLoads.Length; i++)
    2.64 +          coreLoads[i].Value = cpuLoad.GetCoreLoad(i);
    2.65 +        totalLoad.Value = cpuLoad.GetTotalLoad();
    2.66        }
    2.67 -
    2.68 -      for (int i = 0; i < coreLoads.Length; i++)
    2.69 -        if (coreLoadCounters[i] != null) {
    2.70 -          coreLoads[i].Value = coreLoadCounters[i].NextValue();
    2.71 -          ActivateSensor(coreLoads[i]);
    2.72 -        }
    2.73      }
    2.74  
    2.75      private void ActivateSensor(Sensor sensor) {
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/Hardware/CPU/CPULoad.cs	Thu Feb 04 21:19:27 2010 +0000
     3.3 @@ -0,0 +1,161 @@
     3.4 +/*
     3.5 +  
     3.6 +  Version: MPL 1.1/GPL 2.0/LGPL 2.1
     3.7 +
     3.8 +  The contents of this file are subject to the Mozilla Public License Version
     3.9 +  1.1 (the "License"); you may not use this file except in compliance with
    3.10 +  the License. You may obtain a copy of the License at
    3.11 + 
    3.12 +  http://www.mozilla.org/MPL/
    3.13 +
    3.14 +  Software distributed under the License is distributed on an "AS IS" basis,
    3.15 +  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
    3.16 +  for the specific language governing rights and limitations under the License.
    3.17 +
    3.18 +  The Original Code is the Open Hardware Monitor code.
    3.19 +
    3.20 +  The Initial Developer of the Original Code is 
    3.21 +  Michael Möller <m.moeller@gmx.ch>.
    3.22 +  Portions created by the Initial Developer are Copyright (C) 2009-2010
    3.23 +  the Initial Developer. All Rights Reserved.
    3.24 +
    3.25 +  Contributor(s):
    3.26 +
    3.27 +  Alternatively, the contents of this file may be used under the terms of
    3.28 +  either the GNU General Public License Version 2 or later (the "GPL"), or
    3.29 +  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    3.30 +  in which case the provisions of the GPL or the LGPL are applicable instead
    3.31 +  of those above. If you wish to allow use of your version of this file only
    3.32 +  under the terms of either the GPL or the LGPL, and not to allow others to
    3.33 +  use your version of this file under the terms of the MPL, indicate your
    3.34 +  decision by deleting the provisions above and replace them with the notice
    3.35 +  and other provisions required by the GPL or the LGPL. If you do not delete
    3.36 +  the provisions above, a recipient may use your version of this file under
    3.37 +  the terms of any one of the MPL, the GPL or the LGPL.
    3.38 + 
    3.39 +*/
    3.40 +
    3.41 +using System;
    3.42 +using System.Collections.Generic;
    3.43 +using System.Runtime.InteropServices;
    3.44 +using System.Text;
    3.45 +
    3.46 +namespace OpenHardwareMonitor.Hardware.CPU {
    3.47 +  public class CPULoad {
    3.48 +
    3.49 +    [StructLayout(LayoutKind.Sequential)]
    3.50 +    private struct SystemProcessorPerformanceInformation {
    3.51 +      public long IdleTime;
    3.52 +      public long KernelTime;
    3.53 +      public long UserTime;
    3.54 +      public long Reserved0;
    3.55 +      public long Reserved1;
    3.56 +      public ulong Reserved2;
    3.57 +    }
    3.58 +
    3.59 +    private enum SystemInformationClass : int {
    3.60 +      SystemBasicInformation = 0,
    3.61 +      SystemCpuInformation = 1,
    3.62 +      SystemPerformanceInformation = 2,
    3.63 +      SystemTimeOfDayInformation = 3,
    3.64 +      SystemProcessInformation = 5,
    3.65 +      SystemProcessorPerformanceInformation = 8
    3.66 +    }
    3.67 +
    3.68 +    [DllImport("ntdll.dll")]
    3.69 +    private static extern int NtQuerySystemInformation(
    3.70 +      SystemInformationClass informationClass,
    3.71 +      [Out] SystemProcessorPerformanceInformation[] informations, 
    3.72 +      int structSize, out IntPtr returnLength);
    3.73 +
    3.74 +    private uint coreCount;
    3.75 +    private uint logicalProcessorsPerCore;
    3.76 +
    3.77 +    private long systemTime;
    3.78 +    private long[] idleTimes;
    3.79 +
    3.80 +    private float totalLoad;
    3.81 +    private float[] coreLoads;
    3.82 +
    3.83 +    private bool available = false;
    3.84 +
    3.85 +    private long[] GetIdleTimes() {
    3.86 +      long[] result = new long[coreCount * logicalProcessorsPerCore];
    3.87 +      SystemProcessorPerformanceInformation[] informations = new
    3.88 +       SystemProcessorPerformanceInformation[result.Length];
    3.89 +
    3.90 +      IntPtr returnLength;
    3.91 +      NtQuerySystemInformation(
    3.92 +        SystemInformationClass.SystemProcessorPerformanceInformation,
    3.93 +        informations, informations.Length * 
    3.94 +        Marshal.SizeOf(typeof(SystemProcessorPerformanceInformation)),
    3.95 +        out returnLength);
    3.96 +
    3.97 +      for (int i = 0; i < result.Length; i++)
    3.98 +        result[i] = informations[i].IdleTime;
    3.99 +
   3.100 +      return result;
   3.101 +    }
   3.102 +
   3.103 +    public CPULoad(uint coreCount, uint logicalProcessorsPerCore) {
   3.104 +      this.coreCount = coreCount;
   3.105 +      this.logicalProcessorsPerCore = logicalProcessorsPerCore;
   3.106 +      this.coreLoads = new float[coreCount];         
   3.107 +      this.systemTime = DateTime.Now.Ticks;
   3.108 +      this.totalLoad = 0;
   3.109 +      try {
   3.110 +        this.idleTimes = GetIdleTimes();
   3.111 +      } catch (Exception) {
   3.112 +        this.idleTimes = null;
   3.113 +      }
   3.114 +      if (idleTimes != null)
   3.115 +        available = true;
   3.116 +    }
   3.117 +
   3.118 +    public bool IsAvailable {
   3.119 +      get { return available; }
   3.120 +    }
   3.121 +
   3.122 +    public float GetTotalLoad() {
   3.123 +      return totalLoad;
   3.124 +    }
   3.125 +
   3.126 +    public float GetCoreLoad(int core) {
   3.127 +      return coreLoads[core];
   3.128 +    }
   3.129 +
   3.130 +    public void Update() {
   3.131 +      if (this.idleTimes == null)
   3.132 +        return;
   3.133 +
   3.134 +      long systemTime = DateTime.Now.Ticks;
   3.135 +      long[] idleTimes = GetIdleTimes();
   3.136 +
   3.137 +      if (systemTime - this.systemTime < 10000)
   3.138 +        return;
   3.139 +
   3.140 +      float total = 0;
   3.141 +      for (int i = 0; i < coreCount; i++) {
   3.142 +        float value = 0;
   3.143 +        for (int j = 0; j < logicalProcessorsPerCore; j++) {
   3.144 +          long index = i * logicalProcessorsPerCore + j;
   3.145 +          long delta = idleTimes[index] - this.idleTimes[index];
   3.146 +          value += delta;
   3.147 +          total += delta;
   3.148 +        }
   3.149 +        value = 1.0f - value / (logicalProcessorsPerCore * 
   3.150 +          (systemTime - this.systemTime));
   3.151 +        value = value < 0 ? 0 : value;
   3.152 +        coreLoads[i] = value * 100;
   3.153 +      }
   3.154 +      total = 1.0f - total / (coreCount * logicalProcessorsPerCore *
   3.155 +        (systemTime - this.systemTime));
   3.156 +      total = total < 0 ? 0 : total;
   3.157 +      this.totalLoad = total * 100;
   3.158 +
   3.159 +      this.systemTime = systemTime;
   3.160 +      this.idleTimes = idleTimes;
   3.161 +    }
   3.162 +
   3.163 +  }
   3.164 +}
     4.1 --- a/Hardware/CPU/IntelCPU.cs	Wed Feb 03 22:02:58 2010 +0000
     4.2 +++ b/Hardware/CPU/IntelCPU.cs	Thu Feb 04 21:19:27 2010 +0000
     4.3 @@ -59,9 +59,8 @@
     4.4      private uint logicalProcessorsPerCore;
     4.5      private uint coreCount;
     4.6  
     4.7 -    private PerformanceCounter totalLoadCounter;
     4.8 -    private PerformanceCounter[] coreLoadCounters;
     4.9 -
    4.10 +    private CPULoad cpuLoad;
    4.11 +    
    4.12      private const uint IA32_THERM_STATUS_MSR = 0x019C;
    4.13      private const uint IA32_TEMPERATURE_TARGET = 0x01A2;
    4.14  
    4.15 @@ -133,30 +132,7 @@
    4.16          default: tjMax = 100; break;
    4.17        }
    4.18  
    4.19 -      try {
    4.20 -        totalLoadCounter = new PerformanceCounter();
    4.21 -        totalLoadCounter.CategoryName = "Processor";
    4.22 -        totalLoadCounter.CounterName = "% Processor Time";
    4.23 -        totalLoadCounter.InstanceName = "_Total";
    4.24 -        totalLoadCounter.NextValue();        
    4.25 -      } catch (Exception) {
    4.26 -        totalLoadCounter = null;
    4.27 -      }
    4.28 -      totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
    4.29 -
    4.30 -      coreLoadCounters = new PerformanceCounter[
    4.31 -        coreCount * logicalProcessorsPerCore];
    4.32 -      for (int i = 0; i < coreLoadCounters.Length; i++) {
    4.33 -        try {
    4.34 -          coreLoadCounters[i] = new PerformanceCounter();
    4.35 -          coreLoadCounters[i].CategoryName = "Processor";
    4.36 -          coreLoadCounters[i].CounterName = "% Processor Time";
    4.37 -          coreLoadCounters[i].InstanceName = i.ToString();
    4.38 -          coreLoadCounters[i].NextValue();
    4.39 -        } catch (Exception) {
    4.40 -          coreLoadCounters[i] = null;
    4.41 -        }
    4.42 -      }
    4.43 +      totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);     
    4.44  
    4.45        coreTemperatures = new Sensor[coreCount];
    4.46        coreLoads = new Sensor[coreCount];
    4.47 @@ -167,6 +143,13 @@
    4.48            SensorType.Load, this);
    4.49        }
    4.50  
    4.51 +      cpuLoad = new CPULoad(coreCount, logicalProcessorsPerCore);
    4.52 +      if (cpuLoad.IsAvailable) {
    4.53 +        foreach (Sensor sensor in coreLoads)
    4.54 +          ActivateSensor(sensor);
    4.55 +        ActivateSensor(totalLoad);
    4.56 +      }
    4.57 +
    4.58        Update();                   
    4.59      }
    4.60  
    4.61 @@ -221,27 +204,11 @@
    4.62          }        
    4.63        }
    4.64  
    4.65 -      if (totalLoadCounter != null) {
    4.66 -        totalLoad.Value = totalLoadCounter.NextValue();
    4.67 -        ActivateSensor(totalLoad);
    4.68 -      }
    4.69 -
    4.70 -      for (int i = 0; i < coreLoads.Length; i++) {
    4.71 -        float value = 0;
    4.72 -        int count = 0;
    4.73 -        for (int j = 0; j < logicalProcessorsPerCore; j++) {
    4.74 -          PerformanceCounter counter =
    4.75 -            coreLoadCounters[logicalProcessorsPerCore * i + j];
    4.76 -          if (counter != null) {
    4.77 -            value += counter.NextValue();
    4.78 -            count++;
    4.79 -          }
    4.80 -        }
    4.81 -        if (count > 0) {
    4.82 -          value /= count;
    4.83 -          coreLoads[i].Value = value;
    4.84 -          ActivateSensor(coreLoads[i]);
    4.85 -        }
    4.86 +      if (cpuLoad.IsAvailable) {
    4.87 +        cpuLoad.Update();
    4.88 +        for (int i = 0; i < coreLoads.Length; i++)
    4.89 +          coreLoads[i].Value = cpuLoad.GetCoreLoad(i);
    4.90 +        totalLoad.Value = cpuLoad.GetTotalLoad();
    4.91        }
    4.92      }
    4.93  
     5.1 --- a/Hardware/LPC/W83627DHG.cs	Wed Feb 03 22:02:58 2010 +0000
     5.2 +++ b/Hardware/LPC/W83627DHG.cs	Thu Feb 04 21:19:27 2010 +0000
     5.3 @@ -94,7 +94,7 @@
     5.4           (ushort)(address + ADDRESS_REGISTER_OFFSET), register);
     5.5        return WinRing0.ReadIoPortByte(
     5.6          (ushort)(address + DATA_REGISTER_OFFSET));
     5.7 -    }    
     5.8 +    } 
     5.9  
    5.10      public W83627DHG(Chip chip, byte revision, ushort address) {
    5.11        this.chip = chip;
    5.12 @@ -215,14 +215,14 @@
    5.13        foreach (Sensor sensor in temperatures) {
    5.14          int value;
    5.15          if (sensor.Index < 2) {
    5.16 -          value = ReadByte((byte)(sensor.Index + 1), TEMPERATURE_BASE_REG);
    5.17 +          value = (sbyte)ReadByte((byte)(sensor.Index + 1), TEMPERATURE_BASE_REG);
    5.18            value = (value << 1) | ReadByte((byte)(sensor.Index + 1),
    5.19              (byte)(TEMPERATURE_BASE_REG + 1)) >> 7;
    5.20          } else {
    5.21 -          value = ReadByte(0, TEMPERATURE_SYS_REG) << 1;
    5.22 +          value = (sbyte)ReadByte(0, TEMPERATURE_SYS_REG) << 1;
    5.23          }
    5.24          sensor.Value = value / 2.0f;
    5.25 -        if (value < 0x1FE)
    5.26 +        if (value < 0xFE)
    5.27            ActivateSensor(sensor);
    5.28          else
    5.29            DeactivateSensor(sensor);
     6.1 --- a/OpenHardwareMonitor.csproj	Wed Feb 03 22:02:58 2010 +0000
     6.2 +++ b/OpenHardwareMonitor.csproj	Thu Feb 04 21:19:27 2010 +0000
     6.3 @@ -13,6 +13,8 @@
     6.4      <FileAlignment>512</FileAlignment>
     6.5      <RootNamespace>OpenHardwareMonitor</RootNamespace>
     6.6      <ApplicationIcon>Resources\icon.ico</ApplicationIcon>
     6.7 +    <ApplicationManifest>Resources\app.manifest</ApplicationManifest>
     6.8 +    <StartupObject>OpenHardwareMonitor.Program</StartupObject>
     6.9    </PropertyGroup>
    6.10    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    6.11      <DebugSymbols>true</DebugSymbols>
    6.12 @@ -59,6 +61,7 @@
    6.13      <Compile Include="GUI\TypeNode.cs" />
    6.14      <Compile Include="Hardware\CPU\AMD10CPU.cs" />
    6.15      <Compile Include="Hardware\CPU\AMD0FCPU.cs" />
    6.16 +    <Compile Include="Hardware\CPU\CPULoad.cs" />
    6.17      <Compile Include="Hardware\HDD\HDD.cs" />
    6.18      <Compile Include="Hardware\HDD\HDDGroup.cs" />
    6.19      <Compile Include="Hardware\HDD\SMART.cs" />
    6.20 @@ -139,6 +142,9 @@
    6.21      <EmbeddedResource Include="Resources\voltage.png" />
    6.22      <EmbeddedResource Include="Resources\nvidia.png" />
    6.23    </ItemGroup>
    6.24 +  <ItemGroup>
    6.25 +    <None Include="Resources\app.manifest" />
    6.26 +  </ItemGroup>
    6.27    <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
    6.28    <ProjectExtensions>
    6.29      <VisualStudio AllowExistingFolder="true" />
     7.1 --- a/Properties/AssemblyInfo.cs	Wed Feb 03 22:02:58 2010 +0000
     7.2 +++ b/Properties/AssemblyInfo.cs	Thu Feb 04 21:19:27 2010 +0000
     7.3 @@ -69,5 +69,5 @@
     7.4  // You can specify all the values or you can default the Build and Revision Numbers 
     7.5  // by using the '*' as shown below:
     7.6  // [assembly: AssemblyVersion("1.0.*")]
     7.7 -[assembly: AssemblyVersion("0.1.12.0")]
     7.8 -[assembly: AssemblyFileVersion("0.1.12.0")]
     7.9 +[assembly: AssemblyVersion("0.1.13.0")]
    7.10 +[assembly: AssemblyFileVersion("0.1.13.0")]
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/Resources/app.manifest	Thu Feb 04 21:19:27 2010 +0000
     8.3 @@ -0,0 +1,10 @@
     8.4 +<?xml version="1.0" encoding="utf-8"?>
     8.5 +<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     8.6 +  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
     8.7 +    <security>
     8.8 +      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
     8.9 +        <requestedExecutionLevel level="highestAvailable" uiAccess="false" />
    8.10 +      </requestedPrivileges>
    8.11 +    </security>
    8.12 +  </trustInfo>
    8.13 +</asmv1:assembly>
     9.1 --- a/Utilities/HexStringArray.cs	Wed Feb 03 22:02:58 2010 +0000
     9.2 +++ b/Utilities/HexStringArray.cs	Thu Feb 04 21:19:27 2010 +0000
     9.3 @@ -47,8 +47,9 @@
     9.4      public HexStringArray(string input) {
     9.5        List<byte> list = new List<byte>();
     9.6        foreach (string str in input.Split(' ')) {
     9.7 -        if (str.Trim().Length > 0)
     9.8 -          list.Add(Convert.ToByte(str, 16));
     9.9 +        string s = str.Trim();
    9.10 +        if (s.Length > 0)
    9.11 +          list.Add(Convert.ToByte(s, 16));
    9.12        }
    9.13        array = list.ToArray();
    9.14      }