Most basic event action manager.
authorStephaneLenclud
Sat, 23 Jul 2016 16:00:04 +0200
changeset 21083dd86e73448
parent 209 fef4ca058087
child 211 96f8b4dc4300
Most basic event action manager.
Server/ConsumerElectronicControl.cs
Server/MainForm.cs
Server/SharpDisplayManager.csproj
Server/Slions/Ear/Action.cs
Server/Slions/Ear/ActionCallback.cs
Server/Slions/Ear/ActionSleep.cs
Server/Slions/Ear/ActionType.cs
Server/Slions/Ear/Event.cs
Server/Slions/Ear/EventMonitorPowerOff.cs
Server/Slions/Ear/EventMonitorPowerOn.cs
Server/Slions/Ear/Manager.cs
SharpDisplayManager.sln
SharpLibEar/Action.cs
SharpLibEar/ActionCallback.cs
SharpLibEar/ActionSleep.cs
SharpLibEar/ActionType.cs
SharpLibEar/AttributeAction.cs
SharpLibEar/Event.cs
SharpLibEar/EventActionManager.cs
SharpLibEar/EventMonitorPowerOff.cs
SharpLibEar/EventMonitorPowerOn.cs
SharpLibEar/Properties/AssemblyInfo.cs
SharpLibEar/SharpLibEar.csproj
SharpLibUtils/Properties/AssemblyInfo.cs
SharpLibUtils/Reflection.cs
SharpLibUtils/SharpLibUtils.csproj
     1.1 --- a/Server/ConsumerElectronicControl.cs	Fri Jul 22 18:19:49 2016 +0200
     1.2 +++ b/Server/ConsumerElectronicControl.cs	Sat Jul 23 16:00:04 2016 +0200
     1.3 @@ -6,6 +6,7 @@
     1.4  using System.Diagnostics;
     1.5  using System.Windows.Forms;
     1.6  using CecSharp;
     1.7 +using SharpLib.Ear;
     1.8  
     1.9  namespace SharpDisplayManager
    1.10  {
    1.11 @@ -92,12 +93,14 @@
    1.12  
    1.13          private void OnMonitorPowerOn()
    1.14          {
    1.15 +            EventActionManager.Current.GetEvent<EventMonitorPowerOn>().Trigger();
    1.16 +
    1.17              Console.WriteLine("OnMonitorPowerOn");
    1.18  
    1.19              if (iReconnectToPowerTv)
    1.20              {
    1.21                  ConnectCecClient();
    1.22 -            }
    1.23 +            }            
    1.24  
    1.25              //Turn on the TV
    1.26              //iCecClient.Lib.PowerOnDevices(CecLogicalAddress.Tv);
    1.27 @@ -109,6 +112,8 @@
    1.28  
    1.29          private void OnMonitorPowerOff()
    1.30          {
    1.31 +            EventActionManager.Current.GetEvent<EventMonitorPowerOff>().Trigger();
    1.32 +
    1.33              Console.WriteLine("OnMonitorPowerOff");
    1.34  
    1.35              if (iReconnectToPowerTv)
     2.1 --- a/Server/MainForm.cs	Fri Jul 22 18:19:49 2016 +0200
     2.2 +++ b/Server/MainForm.cs	Sat Jul 23 16:00:04 2016 +0200
     2.3 @@ -46,7 +46,7 @@
     2.4  using SharpDisplay;
     2.5  using MiniDisplayInterop;
     2.6  using SharpLib.Display;
     2.7 -using Slions.Ear;
     2.8 +using SharpLib.Ear;
     2.9  
    2.10  namespace SharpDisplayManager
    2.11  {
    2.12 @@ -70,7 +70,7 @@
    2.13  	[System.ComponentModel.DesignerCategory("Form")]
    2.14  	public partial class MainForm : MainFormHid, IMMNotificationClient
    2.15      {
    2.16 -        private Manager iManager = new Manager();
    2.17 +        public EventActionManager iManager = new EventActionManager();        
    2.18          DateTime LastTickTime;
    2.19          Display iDisplay;
    2.20          System.Drawing.Bitmap iBmp;
    2.21 @@ -131,7 +131,8 @@
    2.22  
    2.23          public MainForm()
    2.24          {
    2.25 -			iSkipFrameRendering = false;
    2.26 +            EventActionManager.Current = iManager;
    2.27 +            iSkipFrameRendering = false;
    2.28  			iClosing = false;
    2.29              iCurrentClientSessionId = "";
    2.30              iCurrentClientData = null;
     3.1 --- a/Server/SharpDisplayManager.csproj	Fri Jul 22 18:19:49 2016 +0200
     3.2 +++ b/Server/SharpDisplayManager.csproj	Sat Jul 23 16:00:04 2016 +0200
     3.3 @@ -188,14 +188,6 @@
     3.4      <Compile Include="RichTextBoxTextWriter.cs" />
     3.5      <Compile Include="Session.cs" />
     3.6      <Compile Include="Settings.cs" />
     3.7 -    <Compile Include="Slions\Ear\Action.cs" />
     3.8 -    <Compile Include="Slions\Ear\ActionCallback.cs" />
     3.9 -    <Compile Include="Slions\Ear\ActionSleep.cs" />
    3.10 -    <Compile Include="Slions\Ear\ActionType.cs" />
    3.11 -    <Compile Include="Slions\Ear\Event.cs" />
    3.12 -    <Compile Include="Slions\Ear\EventMonitorPowerOff.cs" />
    3.13 -    <Compile Include="Slions\Ear\EventMonitorPowerOn.cs" />
    3.14 -    <Compile Include="Slions\Ear\Manager.cs" />
    3.15      <Compile Include="StartupManager.cs" />
    3.16      <Compile Include="TaskScheduler.cs" />
    3.17      <Compile Include="Win32API.cs" />
    3.18 @@ -248,6 +240,14 @@
    3.19        <Project>{c174f23d-3055-49bc-b6b0-563011af624d}</Project>
    3.20        <Name>PowerManager</Name>
    3.21      </ProjectReference>
    3.22 +    <ProjectReference Include="..\SharpLibEar\SharpLibEar.csproj">
    3.23 +      <Project>{84a9ed37-e6ea-4cbd-b995-b713f46eaab0}</Project>
    3.24 +      <Name>SharpLibEar</Name>
    3.25 +    </ProjectReference>
    3.26 +    <ProjectReference Include="..\SharpLibUtils\SharpLibUtils.csproj">
    3.27 +      <Project>{ae897704-461d-4018-8336-2517988bf7ad}</Project>
    3.28 +      <Name>SharpLibUtils</Name>
    3.29 +    </ProjectReference>
    3.30    </ItemGroup>
    3.31    <ItemGroup>
    3.32      <BootstrapperPackage Include=".NETFramework,Version=v4.0">
     4.1 --- a/Server/Slions/Ear/Action.cs	Fri Jul 22 18:19:49 2016 +0200
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,16 +0,0 @@
     4.4 -//
     4.5 -
     4.6 -
     4.7 -using System.Runtime.Serialization;
     4.8 -using System.Threading;
     4.9 -
    4.10 -namespace Slions.Ear
    4.11 -{
    4.12 -    [DataContract]
    4.13 -    abstract class Action
    4.14 -    {
    4.15 -        public abstract void Execute();
    4.16 -    }
    4.17 -
    4.18 -
    4.19 -}
    4.20 \ No newline at end of file
     5.1 --- a/Server/Slions/Ear/ActionCallback.cs	Fri Jul 22 18:19:49 2016 +0200
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,29 +0,0 @@
     5.4 -//
     5.5 -
     5.6 -using System.Runtime.Serialization;
     5.7 -
     5.8 -
     5.9 -namespace Slions.Ear
    5.10 -{
    5.11 -    [DataContract]
    5.12 -    abstract class ActionCallback : Action
    5.13 -    {
    5.14 -        public delegate void Delegate();
    5.15 -
    5.16 -        private readonly Delegate iCallback;
    5.17 -
    5.18 -        public ActionCallback(Delegate aCallback = null)
    5.19 -        {
    5.20 -            iCallback = aCallback;
    5.21 -        }
    5.22 -
    5.23 -        public override void Execute()
    5.24 -        {
    5.25 -            if (iCallback != null)
    5.26 -            {
    5.27 -                iCallback.Invoke();
    5.28 -            }            
    5.29 -        }
    5.30 -    }
    5.31 -
    5.32 -}
    5.33 \ No newline at end of file
     6.1 --- a/Server/Slions/Ear/ActionSleep.cs	Fri Jul 22 18:19:49 2016 +0200
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,38 +0,0 @@
     6.4 -//
     6.5 -
     6.6 -
     6.7 -using System.Runtime.Serialization;
     6.8 -using System.Threading;
     6.9 -
    6.10 -namespace Slions.Ear
    6.11 -{
    6.12 -    
    6.13 -
    6.14 -    [DataContract]
    6.15 -    class ActionSleep : Action
    6.16 -    {
    6.17 -        static readonly string Name = "Sleep";
    6.18 -        static readonly string Description = "Have the current thread sleep for the specified amount of milliseconds.";
    6.19 -
    6.20 -        private readonly int iMillisecondsTimeout;
    6.21 -
    6.22 -        public ActionSleep()
    6.23 -        {
    6.24 -            iMillisecondsTimeout = 1000;
    6.25 -        }
    6.26 -
    6.27 -
    6.28 -        public ActionSleep(int aMillisecondsTimeout)
    6.29 -        {
    6.30 -            iMillisecondsTimeout = aMillisecondsTimeout;
    6.31 -        }
    6.32 -
    6.33 -        public override void Execute()
    6.34 -        {
    6.35 -            Thread.Sleep(iMillisecondsTimeout);
    6.36 -        }
    6.37 -    }
    6.38 -
    6.39 -
    6.40 -
    6.41 -}
    6.42 \ No newline at end of file
     7.1 --- a/Server/Slions/Ear/ActionType.cs	Fri Jul 22 18:19:49 2016 +0200
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,19 +0,0 @@
     7.4 -//
     7.5 -
     7.6 -
     7.7 -using System.Runtime.Serialization;
     7.8 -using System.Threading;
     7.9 -
    7.10 -namespace Slions.Ear
    7.11 -{
    7.12 -    [DataContract]
    7.13 -    abstract class ActionType
    7.14 -    {
    7.15 -        [DataMember]
    7.16 -        public string Name { get; protected set;  }
    7.17 -        [DataMember]
    7.18 -        public string Description { get; protected set; }
    7.19 -    }
    7.20 -
    7.21 -
    7.22 -}
    7.23 \ No newline at end of file
     8.1 --- a/Server/Slions/Ear/Event.cs	Fri Jul 22 18:19:49 2016 +0200
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,42 +0,0 @@
     8.4 -//
     8.5 -
     8.6 -
     8.7 -using System;
     8.8 -using System.Collections.Generic;
     8.9 -using System.Runtime.Serialization;
    8.10 -
    8.11 -namespace Slions.Ear
    8.12 -{
    8.13 -    [DataContract]
    8.14 -    abstract class MEvent
    8.15 -    {
    8.16 -        [DataMember]
    8.17 -        public string Name { get; protected set; }
    8.18 -
    8.19 -        [DataMember]
    8.20 -        public string Description { get; protected set; }
    8.21 -
    8.22 -        public abstract void Trigger();
    8.23 -    };
    8.24 -
    8.25 -    [DataContract]
    8.26 -    abstract class Event : MEvent
    8.27 -    {
    8.28 -        List<Action> iActions;
    8.29 -
    8.30 -        protected Event()
    8.31 -        {
    8.32 -            iActions = new List<Action>();
    8.33 -        }
    8.34 -
    8.35 -        public override void Trigger()
    8.36 -        {
    8.37 -            Console.WriteLine("Event '" + Name + "' triggered.");
    8.38 -            foreach (Action action in iActions)
    8.39 -            {
    8.40 -                action.Execute();
    8.41 -            }
    8.42 -        }
    8.43 -    }
    8.44 -
    8.45 -}
    8.46 \ No newline at end of file
     9.1 --- a/Server/Slions/Ear/EventMonitorPowerOff.cs	Fri Jul 22 18:19:49 2016 +0200
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,18 +0,0 @@
     9.4 -//
     9.5 -
     9.6 -
     9.7 -using System.Runtime.Serialization;
     9.8 -
     9.9 -namespace Slions.Ear
    9.10 -{
    9.11 -    [DataContract]
    9.12 -    class EventMonitorPowerOff : Event
    9.13 -    {
    9.14 -        public EventMonitorPowerOff()
    9.15 -        {
    9.16 -            Name = "Monitor Power Off";
    9.17 -            Description = "";
    9.18 -        }
    9.19 -    }
    9.20 -
    9.21 -}
    9.22 \ No newline at end of file
    10.1 --- a/Server/Slions/Ear/EventMonitorPowerOn.cs	Fri Jul 22 18:19:49 2016 +0200
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,19 +0,0 @@
    10.4 -//
    10.5 -
    10.6 -
    10.7 -using System.Runtime.Serialization;
    10.8 -
    10.9 -namespace Slions.Ear
   10.10 -{
   10.11 -    [DataContract]
   10.12 -    class EventMonitorPowerOn : Event
   10.13 -    {
   10.14 -        public EventMonitorPowerOn()
   10.15 -        {
   10.16 -            Name = "Monitor Power On";
   10.17 -            Description = "";
   10.18 -        }
   10.19 -
   10.20 -    }
   10.21 -
   10.22 -}
   10.23 \ No newline at end of file
    11.1 --- a/Server/Slions/Ear/Manager.cs	Fri Jul 22 18:19:49 2016 +0200
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,49 +0,0 @@
    11.4 -//
    11.5 -
    11.6 -
    11.7 -using System;
    11.8 -using System.Collections.Generic;
    11.9 -using System.Linq;
   11.10 -using System.Reflection;
   11.11 -using System.Runtime.Serialization;
   11.12 -
   11.13 -namespace Slions.Ear
   11.14 -{
   11.15 -    public static class ReflectiveEnumerator
   11.16 -    {
   11.17 -        static ReflectiveEnumerator() { }
   11.18 -
   11.19 -        public static IEnumerable<T> GetEnumerableOfType<T>() where T : class
   11.20 -        {
   11.21 -            List<T> objects = new List<T>();
   11.22 -            foreach (Type type in
   11.23 -                Assembly.GetAssembly(typeof(T)).GetTypes()
   11.24 -                .Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(T))))
   11.25 -            {
   11.26 -                objects.Add((T)Activator.CreateInstance(type));
   11.27 -            }
   11.28 -            //objects.Sort();
   11.29 -            return objects;
   11.30 -        }
   11.31 -    }
   11.32 -
   11.33 -
   11.34 -    [DataContract]
   11.35 -    class Manager
   11.36 -    {
   11.37 -        private IEnumerable<Action> Actions;
   11.38 -        private IEnumerable<Event> Events;
   11.39 -
   11.40 -        public Manager()
   11.41 -        {
   11.42 -            Actions = ReflectiveEnumerator.GetEnumerableOfType<Action>();
   11.43 -            Events = ReflectiveEnumerator.GetEnumerableOfType<Event>();
   11.44 -
   11.45 -            //CollectActions();
   11.46 -            //CollectEvents();
   11.47 -        }
   11.48 -
   11.49 -
   11.50 -
   11.51 -    }
   11.52 -}
   11.53 \ No newline at end of file
    12.1 --- a/SharpDisplayManager.sln	Fri Jul 22 18:19:49 2016 +0200
    12.2 +++ b/SharpDisplayManager.sln	Sat Jul 23 16:00:04 2016 +0200
    12.3 @@ -13,6 +13,10 @@
    12.4  EndProject
    12.5  Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpDisplayClientTest", "Clients\Test\SharpDisplayClientTest.csproj", "{7EE64074-8CDB-4448-B40C-81B75D6B31CD}"
    12.6  EndProject
    12.7 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpLibUtils", "SharpLibUtils\SharpLibUtils.csproj", "{AE897704-461D-4018-8336-2517988BF7AD}"
    12.8 +EndProject
    12.9 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpLibEar", "SharpLibEar\SharpLibEar.csproj", "{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}"
   12.10 +EndProject
   12.11  Global
   12.12  	GlobalSection(SolutionConfigurationPlatforms) = preSolution
   12.13  		Debug|Any CPU = Debug|Any CPU
   12.14 @@ -75,6 +79,30 @@
   12.15  		{7EE64074-8CDB-4448-B40C-81B75D6B31CD}.Release|x64.Build.0 = Release|Any CPU
   12.16  		{7EE64074-8CDB-4448-B40C-81B75D6B31CD}.Release|x86.ActiveCfg = Release|x86
   12.17  		{7EE64074-8CDB-4448-B40C-81B75D6B31CD}.Release|x86.Build.0 = Release|x86
   12.18 +		{AE897704-461D-4018-8336-2517988BF7AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
   12.19 +		{AE897704-461D-4018-8336-2517988BF7AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
   12.20 +		{AE897704-461D-4018-8336-2517988BF7AD}.Debug|x64.ActiveCfg = Debug|Any CPU
   12.21 +		{AE897704-461D-4018-8336-2517988BF7AD}.Debug|x64.Build.0 = Debug|Any CPU
   12.22 +		{AE897704-461D-4018-8336-2517988BF7AD}.Debug|x86.ActiveCfg = Debug|Any CPU
   12.23 +		{AE897704-461D-4018-8336-2517988BF7AD}.Debug|x86.Build.0 = Debug|Any CPU
   12.24 +		{AE897704-461D-4018-8336-2517988BF7AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
   12.25 +		{AE897704-461D-4018-8336-2517988BF7AD}.Release|Any CPU.Build.0 = Release|Any CPU
   12.26 +		{AE897704-461D-4018-8336-2517988BF7AD}.Release|x64.ActiveCfg = Release|Any CPU
   12.27 +		{AE897704-461D-4018-8336-2517988BF7AD}.Release|x64.Build.0 = Release|Any CPU
   12.28 +		{AE897704-461D-4018-8336-2517988BF7AD}.Release|x86.ActiveCfg = Release|Any CPU
   12.29 +		{AE897704-461D-4018-8336-2517988BF7AD}.Release|x86.Build.0 = Release|Any CPU
   12.30 +		{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
   12.31 +		{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
   12.32 +		{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}.Debug|x64.ActiveCfg = Debug|Any CPU
   12.33 +		{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}.Debug|x64.Build.0 = Debug|Any CPU
   12.34 +		{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}.Debug|x86.ActiveCfg = Debug|Any CPU
   12.35 +		{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}.Debug|x86.Build.0 = Debug|Any CPU
   12.36 +		{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
   12.37 +		{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}.Release|Any CPU.Build.0 = Release|Any CPU
   12.38 +		{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}.Release|x64.ActiveCfg = Release|Any CPU
   12.39 +		{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}.Release|x64.Build.0 = Release|Any CPU
   12.40 +		{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}.Release|x86.ActiveCfg = Release|Any CPU
   12.41 +		{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}.Release|x86.Build.0 = Release|Any CPU
   12.42  	EndGlobalSection
   12.43  	GlobalSection(SolutionProperties) = preSolution
   12.44  		HideSolutionNode = FALSE
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/SharpLibEar/Action.cs	Sat Jul 23 16:00:04 2016 +0200
    13.3 @@ -0,0 +1,23 @@
    13.4 +//
    13.5 +
    13.6 +
    13.7 +using System;
    13.8 +using System.Runtime.Serialization;
    13.9 +using System.Threading;
   13.10 +
   13.11 +namespace SharpLib.Ear
   13.12 +{
   13.13 +    [DataContract]
   13.14 +    public abstract class Action: IComparable
   13.15 +    {
   13.16 +        public abstract void Execute();
   13.17 +
   13.18 +        public int CompareTo(object obj)
   13.19 +        {
   13.20 +            //Sort by action name
   13.21 +            return Utils.Reflection.GetAttribute<AttributeAction>(GetType()).Name.CompareTo(obj.GetType());            
   13.22 +        }
   13.23 +    }
   13.24 +
   13.25 +
   13.26 +}
   13.27 \ No newline at end of file
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/SharpLibEar/ActionCallback.cs	Sat Jul 23 16:00:04 2016 +0200
    14.3 @@ -0,0 +1,29 @@
    14.4 +//
    14.5 +
    14.6 +using System.Runtime.Serialization;
    14.7 +
    14.8 +
    14.9 +namespace SharpLib.Ear
   14.10 +{
   14.11 +    [DataContract]
   14.12 +    public abstract class ActionCallback : Action
   14.13 +    {
   14.14 +        public delegate void Delegate();
   14.15 +
   14.16 +        private readonly Delegate iCallback;
   14.17 +
   14.18 +        public ActionCallback(Delegate aCallback = null)
   14.19 +        {
   14.20 +            iCallback = aCallback;
   14.21 +        }
   14.22 +
   14.23 +        public override void Execute()
   14.24 +        {
   14.25 +            if (iCallback != null)
   14.26 +            {
   14.27 +                iCallback.Invoke();
   14.28 +            }            
   14.29 +        }
   14.30 +    }
   14.31 +
   14.32 +}
   14.33 \ No newline at end of file
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/SharpLibEar/ActionSleep.cs	Sat Jul 23 16:00:04 2016 +0200
    15.3 @@ -0,0 +1,38 @@
    15.4 +//
    15.5 +
    15.6 +
    15.7 +using System.Runtime.Serialization;
    15.8 +using System.Threading;
    15.9 +
   15.10 +
   15.11 +namespace SharpLib.Ear
   15.12 +{
   15.13 +    
   15.14 +
   15.15 +    [DataContract]
   15.16 +    [AttributeAction(Id = "Thread.Sleep", Name = "Sleep", Description = "Have the current thread sleep for the specified amount of milliseconds.")]
   15.17 +    public class ActionSleep : Action
   15.18 +    {
   15.19 +        private readonly int iMillisecondsTimeout;
   15.20 +
   15.21 +        public ActionSleep()
   15.22 +        {
   15.23 +            iMillisecondsTimeout = 1000;
   15.24 +        }
   15.25 +
   15.26 +
   15.27 +        public ActionSleep(int aMillisecondsTimeout)
   15.28 +        {
   15.29 +            iMillisecondsTimeout = aMillisecondsTimeout;
   15.30 +        }
   15.31 +
   15.32 +        public override void Execute()
   15.33 +        {
   15.34 +            Thread.Sleep(iMillisecondsTimeout);
   15.35 +        }
   15.36 +
   15.37 +    }
   15.38 +
   15.39 +
   15.40 +
   15.41 +}
   15.42 \ No newline at end of file
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/SharpLibEar/ActionType.cs	Sat Jul 23 16:00:04 2016 +0200
    16.3 @@ -0,0 +1,19 @@
    16.4 +//
    16.5 +
    16.6 +
    16.7 +using System.Runtime.Serialization;
    16.8 +using System.Threading;
    16.9 +
   16.10 +namespace SharpLib.Ear
   16.11 +{
   16.12 +    [DataContract]
   16.13 +    public abstract class ActionType
   16.14 +    {
   16.15 +        [DataMember]
   16.16 +        public string Name { get; protected set;  }
   16.17 +        [DataMember]
   16.18 +        public string Description { get; protected set; }
   16.19 +    }
   16.20 +
   16.21 +
   16.22 +}
   16.23 \ No newline at end of file
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/SharpLibEar/AttributeAction.cs	Sat Jul 23 16:00:04 2016 +0200
    17.3 @@ -0,0 +1,19 @@
    17.4 +using System;
    17.5 +using System.Collections.Generic;
    17.6 +using System.Linq;
    17.7 +using System.Text;
    17.8 +using System.Threading.Tasks;
    17.9 +
   17.10 +namespace SharpLib.Ear
   17.11 +{
   17.12 +
   17.13 +    // Multiuse attribute.
   17.14 +    [System.AttributeUsage(System.AttributeTargets.Class)]
   17.15 +    public class AttributeAction : System.Attribute
   17.16 +    {
   17.17 +        public string Id;
   17.18 +        public string Name;
   17.19 +        public string Description;
   17.20 +    }
   17.21 +
   17.22 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/SharpLibEar/Event.cs	Sat Jul 23 16:00:04 2016 +0200
    18.3 @@ -0,0 +1,42 @@
    18.4 +//
    18.5 +
    18.6 +
    18.7 +using System;
    18.8 +using System.Collections.Generic;
    18.9 +using System.Runtime.Serialization;
   18.10 +
   18.11 +namespace SharpLib.Ear
   18.12 +{
   18.13 +    [DataContract]
   18.14 +    public abstract class MEvent
   18.15 +    {
   18.16 +        [DataMember]
   18.17 +        public string Name { get; protected set; }
   18.18 +
   18.19 +        [DataMember]
   18.20 +        public string Description { get; protected set; }
   18.21 +
   18.22 +        public abstract void Trigger();
   18.23 +    };
   18.24 +
   18.25 +    [DataContract]
   18.26 +    public abstract class Event : MEvent
   18.27 +    {
   18.28 +        public List<Action> Actions;
   18.29 +
   18.30 +        protected Event()
   18.31 +        {
   18.32 +           Actions = new List<Action>();
   18.33 +        }
   18.34 +
   18.35 +        public override void Trigger()
   18.36 +        {
   18.37 +            Console.WriteLine("Event '" + Name + "' triggered.");
   18.38 +            foreach (Action action in Actions)
   18.39 +            {
   18.40 +                action.Execute();
   18.41 +            }
   18.42 +        }
   18.43 +    }
   18.44 +
   18.45 +}
   18.46 \ No newline at end of file
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/SharpLibEar/EventActionManager.cs	Sat Jul 23 16:00:04 2016 +0200
    19.3 @@ -0,0 +1,31 @@
    19.4 +//
    19.5 +
    19.6 +
    19.7 +using System;
    19.8 +using System.Collections.Generic;
    19.9 +using System.Linq;
   19.10 +using System.Reflection;
   19.11 +using System.Runtime.Serialization;
   19.12 +
   19.13 +namespace SharpLib.Ear
   19.14 +{
   19.15 +    [DataContract]
   19.16 +    public class EventActionManager
   19.17 +    {
   19.18 +        public static EventActionManager Current = null;
   19.19 +        public IDictionary<string, Type> ActionTypes;
   19.20 +        private IDictionary<string, Event> Events;
   19.21 +
   19.22 +        public EventActionManager()
   19.23 +        {
   19.24 +            ActionTypes = Utils.Reflection.GetConcreteClassesDerivedFromByName<Action>();
   19.25 +            Events = Utils.Reflection.GetConcreteClassesInstanceDerivedFromByName<Event>();
   19.26 +        }
   19.27 +
   19.28 +        public Event GetEvent<T>() where T : class
   19.29 +        {
   19.30 +            return Events[typeof(T).Name];
   19.31 +        }
   19.32 +
   19.33 +    }
   19.34 +}
   19.35 \ No newline at end of file
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/SharpLibEar/EventMonitorPowerOff.cs	Sat Jul 23 16:00:04 2016 +0200
    20.3 @@ -0,0 +1,18 @@
    20.4 +//
    20.5 +
    20.6 +
    20.7 +using System.Runtime.Serialization;
    20.8 +
    20.9 +namespace SharpLib.Ear
   20.10 +{
   20.11 +    [DataContract]
   20.12 +    public class EventMonitorPowerOff : Event
   20.13 +    {
   20.14 +        public EventMonitorPowerOff()
   20.15 +        {
   20.16 +            Name = "Monitor Power Off";
   20.17 +            Description = "";
   20.18 +        }
   20.19 +    }
   20.20 +
   20.21 +}
   20.22 \ No newline at end of file
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/SharpLibEar/EventMonitorPowerOn.cs	Sat Jul 23 16:00:04 2016 +0200
    21.3 @@ -0,0 +1,19 @@
    21.4 +//
    21.5 +
    21.6 +
    21.7 +using System.Runtime.Serialization;
    21.8 +
    21.9 +namespace SharpLib.Ear
   21.10 +{
   21.11 +    [DataContract]
   21.12 +    public class EventMonitorPowerOn : Event
   21.13 +    {
   21.14 +        public EventMonitorPowerOn()
   21.15 +        {
   21.16 +            Name = "Monitor Power On";
   21.17 +            Description = "";
   21.18 +        }
   21.19 +
   21.20 +    }
   21.21 +
   21.22 +}
   21.23 \ No newline at end of file
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/SharpLibEar/Properties/AssemblyInfo.cs	Sat Jul 23 16:00:04 2016 +0200
    22.3 @@ -0,0 +1,36 @@
    22.4 +using System.Reflection;
    22.5 +using System.Runtime.CompilerServices;
    22.6 +using System.Runtime.InteropServices;
    22.7 +
    22.8 +// General Information about an assembly is controlled through the following 
    22.9 +// set of attributes. Change these attribute values to modify the information
   22.10 +// associated with an assembly.
   22.11 +[assembly: AssemblyTitle("SharpLibEar")]
   22.12 +[assembly: AssemblyDescription("")]
   22.13 +[assembly: AssemblyConfiguration("")]
   22.14 +[assembly: AssemblyCompany("")]
   22.15 +[assembly: AssemblyProduct("SharpLibEar")]
   22.16 +[assembly: AssemblyCopyright("Copyright ©  2016")]
   22.17 +[assembly: AssemblyTrademark("")]
   22.18 +[assembly: AssemblyCulture("")]
   22.19 +
   22.20 +// Setting ComVisible to false makes the types in this assembly not visible 
   22.21 +// to COM components.  If you need to access a type in this assembly from 
   22.22 +// COM, set the ComVisible attribute to true on that type.
   22.23 +[assembly: ComVisible(false)]
   22.24 +
   22.25 +// The following GUID is for the ID of the typelib if this project is exposed to COM
   22.26 +[assembly: Guid("84a9ed37-e6ea-4cbd-b995-b713f46eaab0")]
   22.27 +
   22.28 +// Version information for an assembly consists of the following four values:
   22.29 +//
   22.30 +//      Major Version
   22.31 +//      Minor Version 
   22.32 +//      Build Number
   22.33 +//      Revision
   22.34 +//
   22.35 +// You can specify all the values or you can default the Build and Revision Numbers 
   22.36 +// by using the '*' as shown below:
   22.37 +// [assembly: AssemblyVersion("1.0.*")]
   22.38 +[assembly: AssemblyVersion("1.0.0.0")]
   22.39 +[assembly: AssemblyFileVersion("1.0.0.0")]
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/SharpLibEar/SharpLibEar.csproj	Sat Jul 23 16:00:04 2016 +0200
    23.3 @@ -0,0 +1,69 @@
    23.4 +<?xml version="1.0" encoding="utf-8"?>
    23.5 +<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    23.6 +  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
    23.7 +  <PropertyGroup>
    23.8 +    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    23.9 +    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
   23.10 +    <ProjectGuid>{84A9ED37-E6EA-4CBD-B995-B713F46EAAB0}</ProjectGuid>
   23.11 +    <OutputType>Library</OutputType>
   23.12 +    <AppDesignerFolder>Properties</AppDesignerFolder>
   23.13 +    <RootNamespace>SharpLibEar</RootNamespace>
   23.14 +    <AssemblyName>SharpLibEar</AssemblyName>
   23.15 +    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
   23.16 +    <FileAlignment>512</FileAlignment>
   23.17 +  </PropertyGroup>
   23.18 +  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
   23.19 +    <DebugSymbols>true</DebugSymbols>
   23.20 +    <DebugType>full</DebugType>
   23.21 +    <Optimize>false</Optimize>
   23.22 +    <OutputPath>bin\Debug\</OutputPath>
   23.23 +    <DefineConstants>DEBUG;TRACE</DefineConstants>
   23.24 +    <ErrorReport>prompt</ErrorReport>
   23.25 +    <WarningLevel>4</WarningLevel>
   23.26 +  </PropertyGroup>
   23.27 +  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
   23.28 +    <DebugType>pdbonly</DebugType>
   23.29 +    <Optimize>true</Optimize>
   23.30 +    <OutputPath>bin\Release\</OutputPath>
   23.31 +    <DefineConstants>TRACE</DefineConstants>
   23.32 +    <ErrorReport>prompt</ErrorReport>
   23.33 +    <WarningLevel>4</WarningLevel>
   23.34 +  </PropertyGroup>
   23.35 +  <ItemGroup>
   23.36 +    <Reference Include="System" />
   23.37 +    <Reference Include="System.Core" />
   23.38 +    <Reference Include="System.Runtime.Serialization" />
   23.39 +    <Reference Include="System.Xml.Linq" />
   23.40 +    <Reference Include="System.Data.DataSetExtensions" />
   23.41 +    <Reference Include="Microsoft.CSharp" />
   23.42 +    <Reference Include="System.Data" />
   23.43 +    <Reference Include="System.Net.Http" />
   23.44 +    <Reference Include="System.Xml" />
   23.45 +  </ItemGroup>
   23.46 +  <ItemGroup>
   23.47 +    <Compile Include="Action.cs" />
   23.48 +    <Compile Include="ActionCallback.cs" />
   23.49 +    <Compile Include="ActionSleep.cs" />
   23.50 +    <Compile Include="ActionType.cs" />
   23.51 +    <Compile Include="AttributeAction.cs" />
   23.52 +    <Compile Include="Event.cs" />
   23.53 +    <Compile Include="EventMonitorPowerOff.cs" />
   23.54 +    <Compile Include="EventMonitorPowerOn.cs" />
   23.55 +    <Compile Include="EventActionManager.cs" />
   23.56 +    <Compile Include="Properties\AssemblyInfo.cs" />
   23.57 +  </ItemGroup>
   23.58 +  <ItemGroup>
   23.59 +    <ProjectReference Include="..\SharpLibUtils\SharpLibUtils.csproj">
   23.60 +      <Project>{ae897704-461d-4018-8336-2517988bf7ad}</Project>
   23.61 +      <Name>SharpLibUtils</Name>
   23.62 +    </ProjectReference>
   23.63 +  </ItemGroup>
   23.64 +  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   23.65 +  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
   23.66 +       Other similar extension points exist, see Microsoft.Common.targets.
   23.67 +  <Target Name="BeforeBuild">
   23.68 +  </Target>
   23.69 +  <Target Name="AfterBuild">
   23.70 +  </Target>
   23.71 +  -->
   23.72 +</Project>
   23.73 \ No newline at end of file
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/SharpLibUtils/Properties/AssemblyInfo.cs	Sat Jul 23 16:00:04 2016 +0200
    24.3 @@ -0,0 +1,36 @@
    24.4 +using System.Reflection;
    24.5 +using System.Runtime.CompilerServices;
    24.6 +using System.Runtime.InteropServices;
    24.7 +
    24.8 +// General Information about an assembly is controlled through the following 
    24.9 +// set of attributes. Change these attribute values to modify the information
   24.10 +// associated with an assembly.
   24.11 +[assembly: AssemblyTitle("SharpLibUtils")]
   24.12 +[assembly: AssemblyDescription("")]
   24.13 +[assembly: AssemblyConfiguration("")]
   24.14 +[assembly: AssemblyCompany("")]
   24.15 +[assembly: AssemblyProduct("SharpLibUtils")]
   24.16 +[assembly: AssemblyCopyright("Copyright ©  2016")]
   24.17 +[assembly: AssemblyTrademark("")]
   24.18 +[assembly: AssemblyCulture("")]
   24.19 +
   24.20 +// Setting ComVisible to false makes the types in this assembly not visible 
   24.21 +// to COM components.  If you need to access a type in this assembly from 
   24.22 +// COM, set the ComVisible attribute to true on that type.
   24.23 +[assembly: ComVisible(false)]
   24.24 +
   24.25 +// The following GUID is for the ID of the typelib if this project is exposed to COM
   24.26 +[assembly: Guid("ae897704-461d-4018-8336-2517988bf7ad")]
   24.27 +
   24.28 +// Version information for an assembly consists of the following four values:
   24.29 +//
   24.30 +//      Major Version
   24.31 +//      Minor Version 
   24.32 +//      Build Number
   24.33 +//      Revision
   24.34 +//
   24.35 +// You can specify all the values or you can default the Build and Revision Numbers 
   24.36 +// by using the '*' as shown below:
   24.37 +// [assembly: AssemblyVersion("1.0.*")]
   24.38 +[assembly: AssemblyVersion("1.0.0.0")]
   24.39 +[assembly: AssemblyFileVersion("1.0.0.0")]
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/SharpLibUtils/Reflection.cs	Sat Jul 23 16:00:04 2016 +0200
    25.3 @@ -0,0 +1,118 @@
    25.4 +using System;
    25.5 +using System.Collections.Generic;
    25.6 +using System.Linq;
    25.7 +using System.Text;
    25.8 +using System.Threading.Tasks;
    25.9 +using System.Linq;
   25.10 +using System.Reflection;
   25.11 +
   25.12 +
   25.13 +namespace SharpLib.Utils
   25.14 +{
   25.15 +    public class Reflection
   25.16 +    {
   25.17 +        /// <summary>
   25.18 +        /// 
   25.19 +        /// </summary>
   25.20 +        /// <typeparam name="T"></typeparam>
   25.21 +        /// <returns></returns>
   25.22 +        public static IEnumerable<Type> GetConcreteClassesDerivedFrom<T>() where T : class
   25.23 +        {
   25.24 +            List<Type> objects = new List<Type>();
   25.25 +            foreach (Type type in
   25.26 +                Assembly.GetAssembly(typeof(T)).GetTypes()
   25.27 +                .Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(T))))
   25.28 +            {
   25.29 +                objects.Add(type);
   25.30 +            }
   25.31 +
   25.32 +            return objects;
   25.33 +        }
   25.34 +
   25.35 +        /// <summary>
   25.36 +        /// 
   25.37 +        /// </summary>
   25.38 +        /// <typeparam name="T"></typeparam>
   25.39 +        /// <returns></returns>
   25.40 +        public static IDictionary<string, Type> GetConcreteClassesDerivedFromByName<T>() where T : class
   25.41 +        {
   25.42 +            Dictionary<string, Type> objects = new Dictionary<string, Type>();
   25.43 +            foreach (Type type in
   25.44 +                Assembly.GetAssembly(typeof(T)).GetTypes()
   25.45 +                .Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(T))))
   25.46 +            {
   25.47 +                objects.Add(type.Name,type);
   25.48 +            }
   25.49 +
   25.50 +            return objects;
   25.51 +        }
   25.52 +
   25.53 +        /// <summary>
   25.54 +        /// 
   25.55 +        /// </summary>
   25.56 +        /// <typeparam name="T"></typeparam>
   25.57 +        /// <returns></returns>
   25.58 +        public static IEnumerable<T> GetConcreteClassesInstanceDerivedFrom<T>() where T : class
   25.59 +        {
   25.60 +            List<T> objects = new List<T>();
   25.61 +            foreach (Type type in
   25.62 +                Assembly.GetAssembly(typeof(T)).GetTypes()
   25.63 +                .Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(T))))
   25.64 +            {
   25.65 +                objects.Add((T)Activator.CreateInstance(type));
   25.66 +            }
   25.67 +
   25.68 +            if (objects.Count>0
   25.69 +                && objects[0] is IComparable)
   25.70 +            {
   25.71 +                objects.Sort();
   25.72 +            }
   25.73 +
   25.74 +            return objects;
   25.75 +        }
   25.76 +
   25.77 +        /// <summary>
   25.78 +        /// 
   25.79 +        /// </summary>
   25.80 +        /// <typeparam name="T"></typeparam>
   25.81 +        /// <returns></returns>
   25.82 +        public static IDictionary<string, T> GetConcreteClassesInstanceDerivedFromByName<T>() where T : class
   25.83 +        {
   25.84 +            Dictionary<string, T> objects = new Dictionary<string, T>();
   25.85 +            foreach (Type type in
   25.86 +                Assembly.GetAssembly(typeof(T)).GetTypes()
   25.87 +                .Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(T))))
   25.88 +            {
   25.89 +                objects.Add(type.Name,(T)Activator.CreateInstance(type));
   25.90 +            }
   25.91 +
   25.92 +
   25.93 +            return objects;
   25.94 +        }
   25.95 +
   25.96 +
   25.97 +
   25.98 +        /// <summary>
   25.99 +        /// 
  25.100 +        /// </summary>
  25.101 +        /// <typeparam name="T"></typeparam>
  25.102 +        /// <param name="aType"></param>
  25.103 +        /// <returns></returns>
  25.104 +        public static T GetAttribute<T>(Type aType) where T : class
  25.105 +        {
  25.106 +            object[] attrs = aType.GetCustomAttributes(true);
  25.107 +            foreach (object attr in attrs)
  25.108 +            {
  25.109 +                T attribute = attr as T;
  25.110 +                if (attribute != null)
  25.111 +                {
  25.112 +                    return attribute;
  25.113 +                }
  25.114 +            }
  25.115 +
  25.116 +            return null;
  25.117 +        }
  25.118 +
  25.119 +    }
  25.120 +
  25.121 +}
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/SharpLibUtils/SharpLibUtils.csproj	Sat Jul 23 16:00:04 2016 +0200
    26.3 @@ -0,0 +1,54 @@
    26.4 +<?xml version="1.0" encoding="utf-8"?>
    26.5 +<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    26.6 +  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
    26.7 +  <PropertyGroup>
    26.8 +    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    26.9 +    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
   26.10 +    <ProjectGuid>{AE897704-461D-4018-8336-2517988BF7AD}</ProjectGuid>
   26.11 +    <OutputType>Library</OutputType>
   26.12 +    <AppDesignerFolder>Properties</AppDesignerFolder>
   26.13 +    <RootNamespace>SharpLibUtils</RootNamespace>
   26.14 +    <AssemblyName>SharpLibUtils</AssemblyName>
   26.15 +    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
   26.16 +    <FileAlignment>512</FileAlignment>
   26.17 +  </PropertyGroup>
   26.18 +  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
   26.19 +    <DebugSymbols>true</DebugSymbols>
   26.20 +    <DebugType>full</DebugType>
   26.21 +    <Optimize>false</Optimize>
   26.22 +    <OutputPath>bin\Debug\</OutputPath>
   26.23 +    <DefineConstants>DEBUG;TRACE</DefineConstants>
   26.24 +    <ErrorReport>prompt</ErrorReport>
   26.25 +    <WarningLevel>4</WarningLevel>
   26.26 +  </PropertyGroup>
   26.27 +  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
   26.28 +    <DebugType>pdbonly</DebugType>
   26.29 +    <Optimize>true</Optimize>
   26.30 +    <OutputPath>bin\Release\</OutputPath>
   26.31 +    <DefineConstants>TRACE</DefineConstants>
   26.32 +    <ErrorReport>prompt</ErrorReport>
   26.33 +    <WarningLevel>4</WarningLevel>
   26.34 +  </PropertyGroup>
   26.35 +  <ItemGroup>
   26.36 +    <Reference Include="System" />
   26.37 +    <Reference Include="System.Core" />
   26.38 +    <Reference Include="System.Xml.Linq" />
   26.39 +    <Reference Include="System.Data.DataSetExtensions" />
   26.40 +    <Reference Include="Microsoft.CSharp" />
   26.41 +    <Reference Include="System.Data" />
   26.42 +    <Reference Include="System.Net.Http" />
   26.43 +    <Reference Include="System.Xml" />
   26.44 +  </ItemGroup>
   26.45 +  <ItemGroup>
   26.46 +    <Compile Include="Properties\AssemblyInfo.cs" />
   26.47 +    <Compile Include="Reflection.cs" />
   26.48 +  </ItemGroup>
   26.49 +  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   26.50 +  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
   26.51 +       Other similar extension points exist, see Microsoft.Common.targets.
   26.52 +  <Target Name="BeforeBuild">
   26.53 +  </Target>
   26.54 +  <Target Name="AfterBuild">
   26.55 +  </Target>
   26.56 +  -->
   26.57 +</Project>
   26.58 \ No newline at end of file