Support for SharpDisplayManager. MiniDisplay
authorStephaneLenclud
Sun, 21 Sep 2014 21:55:36 +0200 (2014-09-21)
branchMiniDisplay
changeset 445fe4c711fd7f8
parent 444 9b09e2ee0968
child 446 0cb7b9f6a6f8
Support for SharpDisplayManager.
Switching to .NET v4.0 to allow System.ServiceModel.
OxyPlot fix and recompile for .NET v4.0.
FrontView fix to start-up without SoundGraphAccess.exe.
External/OxyPlot.WindowsForms.dll
External/OxyPlot.dll
External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj
External/OxyPlot/OxyPlot/OxyPlot.csproj
GUI/MainForm.Designer.cs
GUI/MainForm.cs
GUI/SensorSharpDisplay.cs
GUI/SharpDisplay.cs
GUI/SharpDisplayClient.cs
GUI/SoundGraphDisplay.cs
OpenHardwareMonitor.csproj
OpenHardwareMonitorLib.csproj
UacHelpers.CppLibrary/UacHelpers.CppLibrary.vcxproj
     1.1 Binary file External/OxyPlot.WindowsForms.dll has changed
     2.1 Binary file External/OxyPlot.dll has changed
     3.1 --- a/External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj	Thu Apr 18 23:25:10 2013 +0200
     3.2 +++ b/External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj	Sun Sep 21 21:55:36 2014 +0200
     3.3 @@ -9,7 +9,7 @@
     3.4      <AppDesignerFolder>Properties</AppDesignerFolder>
     3.5      <RootNamespace>OxyPlot.WindowsForms</RootNamespace>
     3.6      <AssemblyName>OxyPlot.WindowsForms</AssemblyName>
     3.7 -    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
     3.8 +    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
     3.9      <TargetFrameworkProfile>
    3.10      </TargetFrameworkProfile>
    3.11      <FileAlignment>512</FileAlignment>
     4.1 --- a/External/OxyPlot/OxyPlot/OxyPlot.csproj	Thu Apr 18 23:25:10 2013 +0200
     4.2 +++ b/External/OxyPlot/OxyPlot/OxyPlot.csproj	Sun Sep 21 21:55:36 2014 +0200
     4.3 @@ -9,7 +9,7 @@
     4.4      <AppDesignerFolder>Properties</AppDesignerFolder>
     4.5      <RootNamespace>OxyPlot</RootNamespace>
     4.6      <AssemblyName>OxyPlot</AssemblyName>
     4.7 -    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
     4.8 +    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
     4.9      <FileAlignment>512</FileAlignment>
    4.10      <TargetFrameworkProfile>
    4.11      </TargetFrameworkProfile>
    4.12 @@ -93,7 +93,6 @@
    4.13      <Compile Include="Foundation\IDataPoint.cs" />
    4.14      <Compile Include="Foundation\ReflectionHelper.cs" />
    4.15      <Compile Include="Foundation\ScreenPointHelper.cs" />
    4.16 -    <Compile Include="LinqBridge.cs" />
    4.17      <Compile Include="Manipulators\ZoomManipulator.cs" />
    4.18      <Compile Include="Manipulators\ZoomStepManipulator.cs" />
    4.19      <Compile Include="Manipulators\ResetManipulator.cs" />
     5.1 --- a/GUI/MainForm.Designer.cs	Thu Apr 18 23:25:10 2013 +0200
     5.2 +++ b/GUI/MainForm.Designer.cs	Sun Sep 21 21:55:36 2014 +0200
     5.3 @@ -114,6 +114,9 @@
     5.4        this.frontViewMenuItem = new System.Windows.Forms.MenuItem();
     5.5        this.frontViewPackedMenuItem = new System.Windows.Forms.MenuItem();
     5.6        this.frontViewDisplayTimeMenuItem = new System.Windows.Forms.MenuItem();
     5.7 +      this.menuItemSharpDisplay = new System.Windows.Forms.MenuItem();
     5.8 +      this.sharpDisplayPackedMenuItem = new System.Windows.Forms.MenuItem();
     5.9 +      this.sharpDisplayShowTimeMenuItem = new System.Windows.Forms.MenuItem();
    5.10        this.splitContainer.Panel1.SuspendLayout();
    5.11        this.splitContainer.SuspendLayout();
    5.12        this.SuspendLayout();
    5.13 @@ -377,6 +380,7 @@
    5.14              this.logSensorsMenuItem,
    5.15              this.loggingIntervalMenuItem,
    5.16              this.frontViewMenuItem,
    5.17 +            this.menuItemSharpDisplay,
    5.18              this.webMenuItemSeparator,
    5.19              this.webMenuItem});
    5.20        this.optionsMenuItem.Text = "Options";
    5.21 @@ -472,15 +476,33 @@
    5.22        // 
    5.23        this.frontViewDisplayTimeMenuItem.Index = 1;
    5.24        this.frontViewDisplayTimeMenuItem.Text = "Display time";
    5.25 +      //
    5.26 +      // menuItemSharpDisplay
    5.27 +      // 
    5.28 +      this.menuItemSharpDisplay.Index = 11;
    5.29 +      this.menuItemSharpDisplay.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
    5.30 +            this.sharpDisplayPackedMenuItem,
    5.31 +            this.sharpDisplayShowTimeMenuItem});
    5.32 +      this.menuItemSharpDisplay.Text = "SharpDisplay";
    5.33 +      // 
    5.34 +      // sharpDisplayPackedMenuItem
    5.35 +      // 
    5.36 +      this.sharpDisplayPackedMenuItem.Index = 0;
    5.37 +      this.sharpDisplayPackedMenuItem.Text = "Packed";
    5.38 +      // 
    5.39 +      // sharpDisplayDisplayTimeMenuItem
    5.40 +      // 
    5.41 +      this.sharpDisplayShowTimeMenuItem.Index = 1;
    5.42 +      this.sharpDisplayShowTimeMenuItem.Text = "Display Time";
    5.43        // 
    5.44        // webMenuItemSeparator
    5.45        // 
    5.46 -      this.webMenuItemSeparator.Index = 11;
    5.47 +      this.webMenuItemSeparator.Index = 12;
    5.48        this.webMenuItemSeparator.Text = "-";
    5.49        // 
    5.50        // webMenuItem
    5.51        // 
    5.52 -      this.webMenuItem.Index = 12;
    5.53 +      this.webMenuItem.Index = 13;
    5.54        this.webMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
    5.55              this.runWebServerMenuItem,
    5.56              this.serverPortMenuItem});
    5.57 @@ -787,6 +809,9 @@
    5.58      private System.Windows.Forms.MenuItem frontViewMenuItem;
    5.59      private System.Windows.Forms.MenuItem frontViewPackedMenuItem;
    5.60      private System.Windows.Forms.MenuItem frontViewDisplayTimeMenuItem;
    5.61 +    private System.Windows.Forms.MenuItem menuItemSharpDisplay;
    5.62 +    private System.Windows.Forms.MenuItem sharpDisplayPackedMenuItem;
    5.63 +    private System.Windows.Forms.MenuItem sharpDisplayShowTimeMenuItem;
    5.64    }
    5.65  }
    5.66  
     6.1 --- a/GUI/MainForm.cs	Thu Apr 18 23:25:10 2013 +0200
     6.2 +++ b/GUI/MainForm.cs	Sun Sep 21 21:55:36 2014 +0200
     6.3 @@ -39,6 +39,7 @@
     6.4      private Color[] plotColorPalette;
     6.5      private SystemTray systemTray;
     6.6      private SoundGraphDisplay soundGraphDisplay;
     6.7 +    private SharpDisplay sharpDisplay;
     6.8      private bool displayTick;
     6.9      private StartupManager startupManager = new StartupManager();
    6.10      private UpdateVisitor updateVisitor = new UpdateVisitor();
    6.11 @@ -57,6 +58,8 @@
    6.12      private UserOption autoStart;
    6.13      private UserOption frontViewPacked; //Tells whether FrontView should cycle or pack sensors
    6.14      private UserOption frontViewDisplayTime; //Tells whether or not FrontView should display current time
    6.15 +    private UserOption sharpDisplayPacked; //Tells whether SharpDisplay should cycle or pack sensors
    6.16 +    private UserOption sharpDisplayShowTime; //Tells whether or not SharpDisplay should display current time
    6.17  
    6.18      private UserOption readMainboardSensors;
    6.19      private UserOption readCpuSensors;
    6.20 @@ -131,14 +134,18 @@
    6.21        treeView.Model = treeModel;
    6.22  
    6.23        this.computer = new Computer(settings);
    6.24 -
    6.25 +       
    6.26 +      //System tray
    6.27        systemTray = new SystemTray(computer, settings, unitManager);
    6.28        systemTray.HideShowCommand += hideShowClick;
    6.29        systemTray.ExitCommand += exitClick;
    6.30    
    6.31 +      //SoundGraph Display
    6.32        soundGraphDisplay = new SoundGraphDisplay(computer, settings, unitManager);
    6.33 - 
    6.34 -
    6.35 +      //Sharp Display Manager
    6.36 +      sharpDisplay = new SharpDisplay(computer, settings, unitManager);
    6.37 +      
    6.38 +      //
    6.39        int p = (int)Environment.OSVersion.Platform;
    6.40        if ((p == 4) || (p == 128)) { // Unix
    6.41          treeView.RowHeight = Math.Max(treeView.RowHeight, 18); 
    6.42 @@ -233,6 +240,10 @@
    6.43        frontViewPacked = new UserOption("frontViewPackedMenuItem", false, frontViewPackedMenuItem, settings);
    6.44        frontViewDisplayTime = new UserOption("frontViewDisplayTimeMenuItem", false, frontViewDisplayTimeMenuItem, settings);
    6.45  
    6.46 +      sharpDisplayPacked = new UserOption("sharpDisplayPackedMenuItem", false, sharpDisplayPackedMenuItem, settings);
    6.47 +      sharpDisplayShowTime = new UserOption("sharpDisplayShowTimeMenuItem", false, sharpDisplayShowTimeMenuItem, settings);
    6.48 +
    6.49 +
    6.50        readMainboardSensors = new UserOption("mainboardMenuItem", true, 
    6.51          mainboardMenuItem, settings);
    6.52        readMainboardSensors.Changed += delegate(object sender, EventArgs e) {
    6.53 @@ -499,6 +510,14 @@
    6.54                SolidBrush greenBrush = new SolidBrush(Color.FromName("mediumspringgreen"));
    6.55                e.BackgroundBrush = greenBrush;
    6.56            }
    6.57 +
    6.58 +          //If displayed in SharpDisplay draw background in blue
    6.59 +          if (sensorNode != null && settings.GetValue(new Identifier(sensorNode.Sensor.Identifier, "SharpDisplay").ToString(), false))
    6.60 +          {
    6.61 +              SolidBrush aquaBrush = new SolidBrush(Color.FromName("aqua"));
    6.62 +              e.BackgroundBrush = aquaBrush;
    6.63 +          }
    6.64 +
    6.65          } else {
    6.66  
    6.67            e.TextColor = Color.DarkGray;
    6.68 @@ -571,6 +590,11 @@
    6.69            */
    6.70        }  
    6.71  
    6.72 +      if (sharpDisplay != null)
    6.73 +      {
    6.74 +          sharpDisplay.Redraw(sharpDisplayPacked.Value, sharpDisplayShowTime.Value);
    6.75 +      }  
    6.76 +
    6.77  
    6.78        if (logSensors != null && logSensors.Value && delayCount >= 4)
    6.79          logger.Log();
    6.80 @@ -640,6 +664,7 @@
    6.81            server.Quit();
    6.82        systemTray.Dispose();
    6.83        soundGraphDisplay.Dispose();
    6.84 +      sharpDisplay.Dispose();
    6.85      }
    6.86  
    6.87      private void aboutMenuItem_Click(object sender, EventArgs e) {
    6.88 @@ -711,6 +736,18 @@
    6.89                };
    6.90                treeContextMenu.MenuItems.Add(item);
    6.91            }
    6.92 +          {
    6.93 +              MenuItem item = new MenuItem("Show in SharpDisplay");
    6.94 +              item.Checked = sharpDisplay.Contains(node.Sensor);
    6.95 +              item.Click += delegate(object obj, EventArgs args)
    6.96 +              {
    6.97 +                  if (item.Checked)
    6.98 +                      sharpDisplay.Remove(node.Sensor);
    6.99 +                  else
   6.100 +                      sharpDisplay.Add(node.Sensor, true);
   6.101 +              };
   6.102 +              treeContextMenu.MenuItems.Add(item);
   6.103 +          }
   6.104            if (gadget != null) {
   6.105              MenuItem item = new MenuItem("Show in Gadget");
   6.106              item.Checked = gadget.Contains(node.Sensor);
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/GUI/SensorSharpDisplay.cs	Sun Sep 21 21:55:36 2014 +0200
     7.3 @@ -0,0 +1,190 @@
     7.4 +/*
     7.5 + 
     7.6 +  This Source Code Form is subject to the terms of the Mozilla Public
     7.7 +  License, v. 2.0. If a copy of the MPL was not distributed with this
     7.8 +  file, You can obtain one at http://mozilla.org/MPL/2.0/.
     7.9 + 
    7.10 +  Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
    7.11 +	
    7.12 +*/
    7.13 +
    7.14 +using System;
    7.15 +using System.Drawing;
    7.16 +using System.Drawing.Drawing2D;
    7.17 +using System.Drawing.Imaging;
    7.18 +using System.Drawing.Text;
    7.19 +using System.Runtime.InteropServices;
    7.20 +using System.Windows.Forms;
    7.21 +using OpenHardwareMonitor.Hardware;
    7.22 +using OpenHardwareMonitor.Utilities;
    7.23 +
    7.24 +namespace OpenHardwareMonitor.GUI
    7.25 +{
    7.26 +    public class SensorSharpDisplay : IDisposable
    7.27 +    {
    7.28 +
    7.29 +        private UnitManager unitManager;
    7.30 +
    7.31 +        private ISensor sensor;
    7.32 +        private Color color;
    7.33 +        private Color darkColor;
    7.34 +        private Font font;
    7.35 +        private Font smallFont;
    7.36 +        public string iFirstLine;
    7.37 +        public string iSecondLine;
    7.38 +
    7.39 +
    7.40 +        public SensorSharpDisplay(SharpDisplay soundGraphDisplay, ISensor sensor,
    7.41 +          bool balloonTip, PersistentSettings settings, UnitManager unitManager)
    7.42 +        {
    7.43 +            this.unitManager = unitManager;
    7.44 +            this.sensor = sensor;
    7.45 +
    7.46 +            // get the default dpi to create an icon with the correct size
    7.47 +            float dpiX, dpiY;
    7.48 +            using (Bitmap b = new Bitmap(1, 1, PixelFormat.Format32bppArgb))
    7.49 +            {
    7.50 +                dpiX = b.HorizontalResolution;
    7.51 +                dpiY = b.VerticalResolution;
    7.52 +            }
    7.53 +
    7.54 +            // adjust the size of the icon to current dpi (default is 16x16 at 96 dpi) 
    7.55 +            int width = (int)Math.Round(16 * dpiX / 96);
    7.56 +            int height = (int)Math.Round(16 * dpiY / 96);
    7.57 +
    7.58 +            // make sure it does never get smaller than 16x16
    7.59 +            width = width < 16 ? 16 : width;
    7.60 +            height = height < 16 ? 16 : height;
    7.61 +
    7.62 +            // adjust the font size to the icon size
    7.63 +            FontFamily family = SystemFonts.MessageBoxFont.FontFamily;
    7.64 +            float baseSize;
    7.65 +            switch (family.Name)
    7.66 +            {
    7.67 +                case "Segoe UI": baseSize = 12; break;
    7.68 +                case "Tahoma": baseSize = 11; break;
    7.69 +                default: baseSize = 12; break;
    7.70 +            }
    7.71 +
    7.72 +            this.font = new Font(family,
    7.73 +              baseSize * width / 16.0f, GraphicsUnit.Pixel);
    7.74 +            this.smallFont = new Font(family,
    7.75 +              0.75f * baseSize * width / 16.0f, GraphicsUnit.Pixel);
    7.76 +
    7.77 +        }
    7.78 +
    7.79 +        public ISensor Sensor
    7.80 +        {
    7.81 +            get { return sensor; }
    7.82 +        }
    7.83 +
    7.84 +        public Color Color
    7.85 +        {
    7.86 +            get { return color; }
    7.87 +            set
    7.88 +            {
    7.89 +                this.color = value;
    7.90 +                this.darkColor = Color.FromArgb(255,
    7.91 +                  this.color.R / 3,
    7.92 +                  this.color.G / 3,
    7.93 +                  this.color.B / 3);
    7.94 +            }
    7.95 +        }
    7.96 +
    7.97 +        public void Dispose()
    7.98 +        {
    7.99 +            font.Dispose();
   7.100 +            smallFont.Dispose();
   7.101 +        }
   7.102 +
   7.103 +        public string GetString()
   7.104 +        {
   7.105 +            if (!sensor.Value.HasValue)
   7.106 +                return "-";
   7.107 +
   7.108 +            switch (sensor.SensorType)
   7.109 +            {
   7.110 +                case SensorType.Voltage:
   7.111 +                    return string.Format("{0:F1}", sensor.Value);
   7.112 +                case SensorType.Clock:
   7.113 +                    return string.Format("{0:F1}", 1e-3f * sensor.Value);
   7.114 +                case SensorType.Load:
   7.115 +                    return string.Format("{0:F0}", sensor.Value);
   7.116 +                case SensorType.Temperature:
   7.117 +                    if (unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
   7.118 +                        return string.Format("{0:F0}",
   7.119 +                          UnitManager.CelsiusToFahrenheit(sensor.Value));
   7.120 +                    else
   7.121 +                        return string.Format("{0:F0}", sensor.Value);
   7.122 +                case SensorType.Fan:
   7.123 +                    return string.Format("{0:F1}", 1e-3f * sensor.Value);
   7.124 +                case SensorType.Flow:
   7.125 +                    return string.Format("{0:F1}", 1e-3f * sensor.Value);
   7.126 +                case SensorType.Control:
   7.127 +                    return string.Format("{0:F0}", sensor.Value);
   7.128 +                case SensorType.Level:
   7.129 +                    return string.Format("{0:F0}", sensor.Value);
   7.130 +                case SensorType.Power:
   7.131 +                    return string.Format("{0:F0}", sensor.Value);
   7.132 +                case SensorType.Data:
   7.133 +                    return string.Format("{0:F0}", sensor.Value);
   7.134 +                case SensorType.Factor:
   7.135 +                    return string.Format("{0:F1}", sensor.Value);
   7.136 +            }
   7.137 +            return "-";
   7.138 +        }
   7.139 +
   7.140 +
   7.141 +        public void Update()
   7.142 +        {
   7.143 +
   7.144 +
   7.145 +            switch (sensor.SensorType)
   7.146 +            {
   7.147 +                case SensorType.Load:
   7.148 +                case SensorType.Control:
   7.149 +                case SensorType.Level:
   7.150 +                    //notifyIcon.Icon = CreatePercentageIcon();
   7.151 +                    break;
   7.152 +                default:
   7.153 +                    //notifyIcon.Icon = CreateTransparentIcon();
   7.154 +                    break;
   7.155 +            }
   7.156 +
   7.157 +
   7.158 +            string format = "";
   7.159 +            switch (sensor.SensorType)
   7.160 +            {
   7.161 +                case SensorType.Voltage: format = "{0:F2}V"; break;
   7.162 +                case SensorType.Clock: format = "{0:F0}MHz"; break;
   7.163 +                case SensorType.Load: format = "{0:F0}%"; break;
   7.164 +                //iMON VFD escape sequence for Celsius
   7.165 +                case SensorType.Temperature: format = "{0:F0}°C"; break;
   7.166 +                case SensorType.Fan: format = "{0:F0}*"; break; //RPM
   7.167 +                case SensorType.Flow: format = "{0:F0}L/h"; break;
   7.168 +                case SensorType.Control: format = "{0:F0}%"; break;
   7.169 +                case SensorType.Level: format = "{0:F0}%"; break;
   7.170 +                case SensorType.Power: format = "{0:F0}W"; break;
   7.171 +                case SensorType.Data: format = "{0:F0}GB"; break;
   7.172 +                case SensorType.Factor: format = "{0:F3}GB"; break;
   7.173 +            }
   7.174 +            string formattedValue = string.Format(format, sensor.Value);
   7.175 +
   7.176 +            if (sensor.SensorType == SensorType.Temperature &&
   7.177 +              unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
   7.178 +            {
   7.179 +                //iMON VFD escape sequence for Fahrenheit
   7.180 +                format = "{0:F0}°F";
   7.181 +                formattedValue = string.Format(format, UnitManager.CelsiusToFahrenheit(sensor.Value));
   7.182 +            }
   7.183 +
   7.184 +            //iFirstLine = sensor.Hardware.Name;
   7.185 +            //iSecondLine = sensor.Name+ ":" + formattedValue;
   7.186 +
   7.187 +            iFirstLine = sensor.Name;
   7.188 +            iSecondLine = formattedValue;
   7.189 +
   7.190 +
   7.191 +        }
   7.192 +    }
   7.193 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/GUI/SharpDisplay.cs	Sun Sep 21 21:55:36 2014 +0200
     8.3 @@ -0,0 +1,353 @@
     8.4 +/*
     8.5 + 
     8.6 +  This Source Code Form is subject to the terms of the Mozilla Public
     8.7 +  License, v. 2.0. If a copy of the MPL was not distributed with this
     8.8 +  file, You can obtain one at http://mozilla.org/MPL/2.0/.
     8.9 + 
    8.10 +  Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
    8.11 +	
    8.12 +*/
    8.13 +
    8.14 +using System;
    8.15 +using System.Collections.Generic;
    8.16 +using System.Drawing;
    8.17 +using System.Text;
    8.18 +using System.Diagnostics;
    8.19 +using System.Windows.Forms;
    8.20 +using System.Windows;
    8.21 +using OpenHardwareMonitor.Hardware;
    8.22 +using OpenHardwareMonitor.Utilities;
    8.23 +using System.Runtime.InteropServices;
    8.24 +using UacHelpers;
    8.25 +using System.ServiceModel;
    8.26 +using SharpDisplay;
    8.27 +
    8.28 +
    8.29 +namespace OpenHardwareMonitor.GUI
    8.30 +{
    8.31 +    public class SharpDisplay : ICallback, IDisposable
    8.32 +    {
    8.33 +        private IComputer computer;
    8.34 +        private PersistentSettings settings;
    8.35 +        private UnitManager unitManager;
    8.36 +        private List<SensorSharpDisplay> list = new List<SensorSharpDisplay>();
    8.37 +        private global::SharpDisplay.Client iClient;
    8.38 +        TextField iTextFieldTop;
    8.39 +        TextField iTextFieldBottom;
    8.40 +        TextField[] iTextFields;
    8.41 +
    8.42 +        private int iNextSensorToDisplay = 0;
    8.43 +        private int iTickCounter = 0;
    8.44 +
    8.45 +
    8.46 +        public SharpDisplay(IComputer computer, PersistentSettings settings, UnitManager unitManager)
    8.47 +        {
    8.48 +            this.computer = computer;
    8.49 +            this.settings = settings;
    8.50 +            this.unitManager = unitManager;
    8.51 +            computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
    8.52 +            computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
    8.53 +
    8.54 +            //Connect our client
    8.55 +            //Instance context is then managed by our client class
    8.56 +            iClient = new global::SharpDisplay.Client(this);
    8.57 +            //
    8.58 +            iTextFieldTop = new TextField(0);
    8.59 +            iTextFieldBottom = new TextField(1);
    8.60 +            iTextFields = new TextField[] { iTextFieldTop, iTextFieldBottom };
    8.61 +
    8.62 +        }
    8.63 +
    8.64 +        //From ICallback
    8.65 +        public void OnConnected()
    8.66 +        {
    8.67 +            //Debug.Assert(Thread.CurrentThread.IsThreadPoolThread);
    8.68 +            //Trace.WriteLine("Callback thread = " + Thread.CurrentThread.ManagedThreadId);
    8.69 +            //MessageBox.Show("OnConnected()", "Client");
    8.70 +        }
    8.71 +
    8.72 +        //From ICallback
    8.73 +        public void OnCloseOrder()
    8.74 +        {
    8.75 +            iClient.Close();
    8.76 +        }
    8.77 +
    8.78 +
    8.79 +        private void HardwareRemoved(IHardware hardware)
    8.80 +        {
    8.81 +            hardware.SensorAdded -= new SensorEventHandler(SensorAdded);
    8.82 +            hardware.SensorRemoved -= new SensorEventHandler(SensorRemoved);
    8.83 +            foreach (ISensor sensor in hardware.Sensors)
    8.84 +                SensorRemoved(sensor);
    8.85 +            foreach (IHardware subHardware in hardware.SubHardware)
    8.86 +                HardwareRemoved(subHardware);
    8.87 +        }
    8.88 +
    8.89 +        private void HardwareAdded(IHardware hardware)
    8.90 +        {
    8.91 +            foreach (ISensor sensor in hardware.Sensors)
    8.92 +                SensorAdded(sensor);
    8.93 +            hardware.SensorAdded += new SensorEventHandler(SensorAdded);
    8.94 +            hardware.SensorRemoved += new SensorEventHandler(SensorRemoved);
    8.95 +            foreach (IHardware subHardware in hardware.SubHardware)
    8.96 +                HardwareAdded(subHardware);
    8.97 +        }
    8.98 +
    8.99 +        private void SensorAdded(ISensor sensor)
   8.100 +        {
   8.101 +            if (settings.GetValue(new Identifier(sensor.Identifier,
   8.102 +              "SharpDisplay").ToString(), false))
   8.103 +                Add(sensor, false);
   8.104 +        }
   8.105 +
   8.106 +        private void SensorRemoved(ISensor sensor)
   8.107 +        {
   8.108 +            if (Contains(sensor))
   8.109 +                Remove(sensor, false);
   8.110 +        }
   8.111 +
   8.112 +        public void Dispose()
   8.113 +        {
   8.114 +            foreach (SensorSharpDisplay icon in list)
   8.115 +                icon.Dispose();
   8.116 +
   8.117 +            Quit();            
   8.118 +            //iServer.Stop();
   8.119 +            iClient.Close();
   8.120 +
   8.121 +        }
   8.122 +
   8.123 +        public void Redraw(bool aPacked, bool aDisplayTime)
   8.124 +        {
   8.125 +            const int KNumberOfTickBeforeSwitch = 4;
   8.126 +            const int KMaxCharacterPerLine = 16;
   8.127 +            string packedFirstLine = ""; //We have 16 chars per line on our VFD
   8.128 +            string packedSecondLine = "";
   8.129 +            int count = 0;
   8.130 +
   8.131 +            string time = DateTime.Now.ToShortTimeString();
   8.132 +
   8.133 +            //Update all sensors from our front view
   8.134 +            foreach (SensorSharpDisplay sensor in list)
   8.135 +            {
   8.136 +                count++;
   8.137 +                sensor.Update();
   8.138 +
   8.139 +                if (aDisplayTime && count == 1)
   8.140 +                {
   8.141 +                    //First slot is take by time display
   8.142 +                    count++;
   8.143 +                    packedFirstLine = time + " ";
   8.144 +                }
   8.145 +
   8.146 +                if (aPacked)
   8.147 +                {
   8.148 +                    //Build strings for packed mode
   8.149 +                    string packedText = "";
   8.150 +                    packedText = sensor.iFirstLine.Substring(0, 3) + ":" + sensor.iSecondLine;
   8.151 +                    if (count == 1)
   8.152 +                    {
   8.153 +                        packedFirstLine = packedText + " "; //Minimum one space to separate sensors on the same line
   8.154 +                    }
   8.155 +                    else if (count == 2)
   8.156 +                    {
   8.157 +                        //Add enough spaces to align to right hand side
   8.158 +                        while (packedFirstLine.Length + packedText.Length < KMaxCharacterPerLine)
   8.159 +                        {
   8.160 +                            packedFirstLine += " ";
   8.161 +                        }
   8.162 +                        packedFirstLine += packedText;
   8.163 +                    }
   8.164 +                    else if (count == 3)
   8.165 +                    {
   8.166 +                        packedSecondLine = packedText + " "; //Minimum one space to separate sensors on the same line
   8.167 +                    }
   8.168 +                    else if (count == 4)
   8.169 +                    {
   8.170 +                        //Add enough spaces to align to right hand side
   8.171 +                        while (packedSecondLine.Length + packedText.Length < KMaxCharacterPerLine)
   8.172 +                        {
   8.173 +                            packedSecondLine += " ";
   8.174 +                        }
   8.175 +                        packedSecondLine += packedText;
   8.176 +                    }
   8.177 +                }
   8.178 +                //SetText(sensor.iFirstLine, sensor.iSecondLine);
   8.179 +            }
   8.180 +
   8.181 +            //Alternate between sensors 
   8.182 +            if (list.Count > 0)
   8.183 +            {
   8.184 +                if (aPacked)
   8.185 +                {
   8.186 +                    //string packedLine = "";
   8.187 +                    iTickCounter++;
   8.188 +                    if (iTickCounter == KNumberOfTickBeforeSwitch) //Move to the next sensor only every so many tick
   8.189 +                    {
   8.190 +                        iTickCounter = 0;
   8.191 +                        if (iNextSensorToDisplay == 1)
   8.192 +                        {
   8.193 +                            iNextSensorToDisplay = 0;
   8.194 +                        }
   8.195 +                        else
   8.196 +                        {
   8.197 +                            iNextSensorToDisplay = 1;
   8.198 +                        }
   8.199 +                    }
   8.200 +
   8.201 +                    //TODO: Do something like that to cycle lines if ever we want to
   8.202 +                    //SetText(time, (iNextSensorToDisplay == 1 && packedSecondLine.Length > 0 ? packedSecondLine : packedFirstLine));
   8.203 +
   8.204 +                    //Display packed sensors on our FrontView display
   8.205 +                    SetText(packedFirstLine, packedSecondLine);
   8.206 +                }
   8.207 +                else
   8.208 +                {
   8.209 +                    string secondLine = list[iNextSensorToDisplay].iSecondLine;
   8.210 +                    if (aDisplayTime)
   8.211 +                    {
   8.212 +                        //Add enough spaces
   8.213 +                        while (secondLine.Length + time.Length < KMaxCharacterPerLine)
   8.214 +                        {
   8.215 +                            secondLine += " ";
   8.216 +                        }
   8.217 +                        secondLine += time;
   8.218 +                    }
   8.219 +                    //Display current sensor on our FrontView display
   8.220 +                    SetText(list[iNextSensorToDisplay].iFirstLine, secondLine);
   8.221 +                    iTickCounter++;
   8.222 +                    if (iTickCounter == KNumberOfTickBeforeSwitch) //Move to the next sensor only every so many tick
   8.223 +                    {
   8.224 +                        iTickCounter = 0;
   8.225 +                        iNextSensorToDisplay++;
   8.226 +                    }
   8.227 +                }
   8.228 +            }
   8.229 +
   8.230 +            if (iNextSensorToDisplay == list.Count)
   8.231 +            {
   8.232 +                //Go back to first sensor
   8.233 +                iNextSensorToDisplay = 0;
   8.234 +            }
   8.235 +
   8.236 +
   8.237 +        }
   8.238 +
   8.239 +        public bool Contains(ISensor sensor)
   8.240 +        {
   8.241 +            foreach (SensorSharpDisplay icon in list)
   8.242 +                if (icon.Sensor == sensor)
   8.243 +                    return true;
   8.244 +            return false;
   8.245 +        }
   8.246 +
   8.247 +        public void Add(ISensor sensor, bool balloonTip)
   8.248 +        {
   8.249 +            if (Contains(sensor))
   8.250 +            {
   8.251 +                return;
   8.252 +            }
   8.253 +            else
   8.254 +            {
   8.255 +                //SL:
   8.256 +                list.Add(new SensorSharpDisplay(this, sensor, balloonTip, settings, unitManager));
   8.257 +                //UpdateMainIconVisibilty();
   8.258 +                settings.SetValue(new Identifier(sensor.Identifier, "SharpDisplay").ToString(), true);
   8.259 +                iNextSensorToDisplay = 0;
   8.260 +                if (list.Count == 1)
   8.261 +                {
   8.262 +                    //Just added first sensor in FrontView, unable FrontView plug-in mode
   8.263 +                    Init();
   8.264 +                }
   8.265 +            }
   8.266 +
   8.267 +        }
   8.268 +
   8.269 +        public void Remove(ISensor sensor)
   8.270 +        {
   8.271 +            Remove(sensor, true);
   8.272 +            iNextSensorToDisplay = 0;
   8.273 +            if (list.Count == 0)
   8.274 +            {
   8.275 +                //No sensor to display in FrontView, just disable FrontView plug-in mode
   8.276 +                Uninit();
   8.277 +            }
   8.278 +
   8.279 +        }
   8.280 +
   8.281 +        private void Remove(ISensor sensor, bool deleteConfig)
   8.282 +        {
   8.283 +            if (deleteConfig)
   8.284 +            {
   8.285 +                settings.Remove(
   8.286 +                  new Identifier(sensor.Identifier, "SharpDisplay").ToString());
   8.287 +            }
   8.288 +            SensorSharpDisplay instance = null;
   8.289 +            foreach (SensorSharpDisplay icon in list)
   8.290 +                if (icon.Sensor == sensor)
   8.291 +                    instance = icon;
   8.292 +            if (instance != null)
   8.293 +            {
   8.294 +                list.Remove(instance);
   8.295 +                //UpdateMainIconVisibilty();
   8.296 +                instance.Dispose();
   8.297 +            }
   8.298 +        }
   8.299 +
   8.300 +
   8.301 +
   8.302 +        private void UpdateMainIconVisibilty()
   8.303 +        {
   8.304 +            /*
   8.305 +            if (mainIconEnabled)
   8.306 +            {
   8.307 +                mainIcon.Visible = list.Count == 0;
   8.308 +            }
   8.309 +            else
   8.310 +            {
   8.311 +                mainIcon.Visible = false;
   8.312 +            }
   8.313 +             */
   8.314 +        }
   8.315 +
   8.316 +        public void Init()
   8.317 +        {
   8.318 +            //iServer.SendMessage("init:");
   8.319 +        }
   8.320 +
   8.321 +        public void Uninit()
   8.322 +        {
   8.323 +            //iServer.SendMessage("uninit:");
   8.324 +        }
   8.325 +
   8.326 +        public void SetText(string aUpperLine, string aLowerLine)
   8.327 +        {
   8.328 +            //iServer.SendMessage("set-vfd-text:" + aUpperLine + "\n" + aLowerLine);
   8.329 +            iTextFieldTop.Text = aUpperLine;
   8.330 +            iTextFieldBottom.Text = aLowerLine;
   8.331 +            iClient.SetTexts(iTextFields);
   8.332 +
   8.333 +        }
   8.334 +
   8.335 +        public void Quit()
   8.336 +        {
   8.337 +            //iServer.SendMessage("quit:");
   8.338 +        }
   8.339 +
   8.340 +        /*
   8.341 +        public bool IsMainIconEnabled
   8.342 +        {
   8.343 +            get { return mainIconEnabled; }
   8.344 +            set
   8.345 +            {
   8.346 +                if (mainIconEnabled != value)
   8.347 +                {
   8.348 +                    mainIconEnabled = value;
   8.349 +                    UpdateMainIconVisibilty();
   8.350 +                }
   8.351 +            }
   8.352 +        }*/
   8.353 +
   8.354 +
   8.355 +    }
   8.356 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/GUI/SharpDisplayClient.cs	Sun Sep 21 21:55:36 2014 +0200
     9.3 @@ -0,0 +1,159 @@
     9.4 +/*
     9.5 + 
     9.6 +  This Source Code Form is subject to the terms of the Mozilla Public
     9.7 +  License, v. 2.0. If a copy of the MPL was not distributed with this
     9.8 +  file, You can obtain one at http://mozilla.org/MPL/2.0/.
     9.9 + 
    9.10 +  Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
    9.11 +	
    9.12 +*/
    9.13 +
    9.14 +using System;
    9.15 +using System.Collections.Generic;
    9.16 +using System.Drawing;
    9.17 +using System.Text;
    9.18 +using System.Diagnostics;
    9.19 +using System.Windows.Forms;
    9.20 +using System.Windows;
    9.21 +using OpenHardwareMonitor.Hardware;
    9.22 +using OpenHardwareMonitor.Utilities;
    9.23 +using System.Runtime.InteropServices;
    9.24 +using UacHelpers;
    9.25 +//
    9.26 +using System.ServiceModel;
    9.27 +using System.Runtime.Serialization;
    9.28 +using SharpDisplay;
    9.29 +
    9.30 +namespace SharpDisplay
    9.31 +{
    9.32 +    //That contract need to be in the same namespace than the original assembly
    9.33 +    //otherwise our parameter won't make to the server.
    9.34 +    //See: http://stackoverflow.com/questions/14956377/passing-an-object-using-datacontract-in-wcf/25455292#25455292
    9.35 +    [DataContract]
    9.36 +    public class TextField
    9.37 +    {
    9.38 +        public TextField()
    9.39 +        {
    9.40 +            Index = 0;
    9.41 +            Text = "";
    9.42 +            Alignment = ContentAlignment.MiddleLeft;
    9.43 +        }
    9.44 +
    9.45 +        public TextField(int aIndex, string aText = "", ContentAlignment aAlignment = ContentAlignment.MiddleLeft)
    9.46 +        {
    9.47 +            Index = aIndex;
    9.48 +            Text = aText;
    9.49 +            Alignment = aAlignment;
    9.50 +        }
    9.51 +
    9.52 +        [DataMember]
    9.53 +        public int Index { get; set; }
    9.54 +
    9.55 +        [DataMember]
    9.56 +        public string Text { get; set; }
    9.57 +
    9.58 +        [DataMember]
    9.59 +        public ContentAlignment Alignment { get; set; }
    9.60 +    }
    9.61 +
    9.62 +
    9.63 +    [ServiceContract(CallbackContract = typeof(ICallback), SessionMode = SessionMode.Required)]
    9.64 +    public interface IService
    9.65 +    {
    9.66 +        /// <summary>
    9.67 +        /// Set the name of this client.
    9.68 +        /// Name is a convenient way to recognize your client.
    9.69 +        /// Naming you client is not mandatory.
    9.70 +        /// In the absence of a name the session ID is often used instead.
    9.71 +        /// </summary>
    9.72 +        /// <param name="aClientName"></param>
    9.73 +        [OperationContract(IsOneWay = true)]
    9.74 +        void SetName(string aClientName);
    9.75 +
    9.76 +        /// <summary>
    9.77 +        /// Put the given text in the given field on your display.
    9.78 +        /// Fields are often just lines of text.
    9.79 +        /// </summary>
    9.80 +        /// <param name="aTextFieldIndex"></param>
    9.81 +        [OperationContract(IsOneWay = true)]
    9.82 +        void SetText(TextField aTextField);
    9.83 +
    9.84 +        /// <summary>
    9.85 +        /// Allows a client to set multiple text fields at once.
    9.86 +        /// </summary>
    9.87 +        /// <param name="aTexts"></param>
    9.88 +        [OperationContract(IsOneWay = true)]
    9.89 +        void SetTexts(System.Collections.Generic.IList<TextField> aTextFields);
    9.90 +
    9.91 +        /// <summary>
    9.92 +        /// Provides the number of clients currently connected
    9.93 +        /// </summary>
    9.94 +        /// <returns></returns>
    9.95 +        [OperationContract()]
    9.96 +        int ClientCount();
    9.97 +
    9.98 +    }
    9.99 +
   9.100 +
   9.101 +    public interface ICallback
   9.102 +    {
   9.103 +        [OperationContract(IsOneWay = true)]
   9.104 +        void OnConnected();
   9.105 +
   9.106 +        /// <summary>
   9.107 +        /// Tell our client to close its connection.
   9.108 +        /// Notably sent when the server is shutting down.
   9.109 +        /// </summary>
   9.110 +        [OperationContract(IsOneWay = true)]
   9.111 +        void OnCloseOrder();
   9.112 +    }
   9.113 +}
   9.114 +
   9.115 +
   9.116 +
   9.117 +namespace SharpDisplay
   9.118 +{
   9.119 +
   9.120 +    /// <summary>
   9.121 +    ///
   9.122 +    /// </summary>
   9.123 +    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
   9.124 +    public class Client : DuplexClientBase<IService>
   9.125 +    {
   9.126 +        public string Name { get; set; }
   9.127 +        public string SessionId { get { return InnerChannel.SessionId; } }
   9.128 +
   9.129 +        public Client(ICallback aCallback)
   9.130 +            : base(new InstanceContext(aCallback), new NetTcpBinding(SecurityMode.None, true), new EndpointAddress("net.tcp://localhost:8001/DisplayService"))
   9.131 +        { }
   9.132 +
   9.133 +        public void SetName(string aClientName)
   9.134 +        {
   9.135 +            Name = aClientName;
   9.136 +            Channel.SetName(aClientName);
   9.137 +        }
   9.138 +
   9.139 +        public void SetText(TextField aTextField)
   9.140 +        {
   9.141 +            Channel.SetText(aTextField);
   9.142 +        }
   9.143 +
   9.144 +        public void SetTexts(System.Collections.Generic.IList<TextField> aTextFields)
   9.145 +        {
   9.146 +            Channel.SetTexts(aTextFields);
   9.147 +        }
   9.148 +
   9.149 +        public int ClientCount()
   9.150 +        {
   9.151 +            return Channel.ClientCount();
   9.152 +        }
   9.153 +
   9.154 +        public bool IsReady()
   9.155 +        {
   9.156 +            return State == CommunicationState.Opened;
   9.157 +        }
   9.158 +
   9.159 +    }
   9.160 +
   9.161 +
   9.162 +}
   9.163 \ No newline at end of file
    10.1 --- a/GUI/SoundGraphDisplay.cs	Thu Apr 18 23:25:10 2013 +0200
    10.2 +++ b/GUI/SoundGraphDisplay.cs	Sun Sep 21 21:55:36 2014 +0200
    10.3 @@ -53,10 +53,17 @@
    10.4              Process[] processes = Process.GetProcessesByName("SoundGraphAccess");
    10.5              if (!(processes.Length > 0))
    10.6              {
    10.7 +              try
    10.8 +              {
    10.9                  //Try to launch the sound graph process from the same folder as this executable
   10.10 -                string exeName=System.IO.Path.GetDirectoryName(Application.ExecutablePath);
   10.11 +                string exeName = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
   10.12                  exeName += @"\SoundGraphAccess.exe";
   10.13 -                Process client = UserAccountControl.CreateProcessAsStandardUser(exeName,"");
   10.14 +                Process client = UserAccountControl.CreateProcessAsStandardUser(exeName, "");
   10.15 +              }
   10.16 +              catch (Exception e)
   10.17 +              {
   10.18 +                Debug.WriteLine("SoundGraphAccess.exe start-up failed: " + e.ToString());
   10.19 +              }
   10.20              }
   10.21  
   10.22              //Start our SoundGraph server
    11.1 --- a/OpenHardwareMonitor.csproj	Thu Apr 18 23:25:10 2013 +0200
    11.2 +++ b/OpenHardwareMonitor.csproj	Sun Sep 21 21:55:36 2014 +0200
    11.3 @@ -9,7 +9,7 @@
    11.4      <OutputType>WinExe</OutputType>
    11.5      <NoStandardLibraries>false</NoStandardLibraries>
    11.6      <AssemblyName>OpenHardwareMonitor</AssemblyName>
    11.7 -    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
    11.8 +    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    11.9      <FileAlignment>512</FileAlignment>
   11.10      <RootNamespace>OpenHardwareMonitor</RootNamespace>
   11.11      <ApplicationIcon>Resources\icon.ico</ApplicationIcon>
   11.12 @@ -34,6 +34,7 @@
   11.13      <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
   11.14      <UseApplicationTrust>false</UseApplicationTrust>
   11.15      <BootstrapperEnabled>true</BootstrapperEnabled>
   11.16 +    <TargetFrameworkProfile />
   11.17    </PropertyGroup>
   11.18    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
   11.19      <DebugSymbols>true</DebugSymbols>
   11.20 @@ -68,6 +69,8 @@
   11.21      <Reference Include="System.Configuration.Install" />
   11.22      <Reference Include="System.Drawing" />
   11.23      <Reference Include="System.Management" />
   11.24 +    <Reference Include="System.Runtime.Serialization" />
   11.25 +    <Reference Include="System.ServiceModel" />
   11.26      <Reference Include="System.Windows.Forms" />
   11.27      <Reference Include="System.Xml" />
   11.28      <Reference Include="Aga.Controls, Version=1.7.0.0, Culture=neutral, PublicKeyToken=fcc90fbf924463a3">
   11.29 @@ -111,6 +114,9 @@
   11.30      <Compile Include="GUI\SensorFrontView.cs" />
   11.31      <Compile Include="GUI\SensorGadget.cs" />
   11.32      <Compile Include="GUI\SensorNotifyIcon.cs" />
   11.33 +    <Compile Include="GUI\SensorSharpDisplay.cs" />
   11.34 +    <Compile Include="GUI\SharpDisplay.cs" />
   11.35 +    <Compile Include="GUI\SharpDisplayClient.cs" />
   11.36      <Compile Include="GUI\ShowDesktop.cs" />
   11.37      <Compile Include="GUI\SoundGraphDisplay.cs" />
   11.38      <Compile Include="GUI\SoundGraphServer.cs" />
    12.1 --- a/OpenHardwareMonitorLib.csproj	Thu Apr 18 23:25:10 2013 +0200
    12.2 +++ b/OpenHardwareMonitorLib.csproj	Sun Sep 21 21:55:36 2014 +0200
    12.3 @@ -10,7 +10,7 @@
    12.4      <AppDesignerFolder>Properties</AppDesignerFolder>
    12.5      <RootNamespace>OpenHardwareMonitor</RootNamespace>
    12.6      <AssemblyName>OpenHardwareMonitorLib</AssemblyName>
    12.7 -    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
    12.8 +    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    12.9      <FileAlignment>512</FileAlignment>
   12.10      <FileUpgradeFlags>
   12.11      </FileUpgradeFlags>
   12.12 @@ -31,6 +31,7 @@
   12.13      <IsWebBootstrapper>false</IsWebBootstrapper>
   12.14      <UseApplicationTrust>false</UseApplicationTrust>
   12.15      <BootstrapperEnabled>true</BootstrapperEnabled>
   12.16 +    <TargetFrameworkProfile />
   12.17    </PropertyGroup>
   12.18    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
   12.19      <DebugSymbols>true</DebugSymbols>
    13.1 --- a/UacHelpers.CppLibrary/UacHelpers.CppLibrary.vcxproj	Thu Apr 18 23:25:10 2013 +0200
    13.2 +++ b/UacHelpers.CppLibrary/UacHelpers.CppLibrary.vcxproj	Sun Sep 21 21:55:36 2014 +0200
    13.3 @@ -19,7 +19,7 @@
    13.4      </ProjectConfiguration>
    13.5    </ItemGroup>
    13.6    <PropertyGroup Label="Globals">
    13.7 -    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
    13.8 +    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    13.9      <ProjectName>UacHelpers.UserAccountControl</ProjectName>
   13.10      <ProjectGuid>{D043A646-FE7A-4334-B23D-E327593C1AE2}</ProjectGuid>
   13.11      <RootNamespace>UacHelpersCppLibrary</RootNamespace>