From: <an...@us...> - 2007-09-18 14:18:32
|
Revision: 937 http://mp-plugins.svn.sourceforge.net/mp-plugins/?rev=937&view=rev Author: and-81 Date: 2007-09-18 07:00:39 -0700 (Tue, 18 Sep 2007) Log Message: ----------- Modified Paths: -------------- trunk/plugins/IR Server Suite/Common/IrssComms/Client.cs trunk/plugins/IR Server Suite/Common/IrssComms/IrssComms.csproj trunk/plugins/IR Server Suite/Common/IrssComms/Server.cs Added Paths: ----------- trunk/plugins/IR Server Suite/Common/IrssComms/GenericPCQueue.cs trunk/plugins/IR Server Suite/Input Service/ trunk/plugins/IR Server Suite/Input Service/Input Service.csproj trunk/plugins/IR Server Suite/Input Service/InputService.cs trunk/plugins/IR Server Suite/Input Service/InputServiceInstaller.cs trunk/plugins/IR Server Suite/Input Service/Program.cs trunk/plugins/IR Server Suite/Input Service/Properties/ trunk/plugins/IR Server Suite/Input Service/Properties/AssemblyInfo.cs Removed Paths: ------------- trunk/plugins/IR Server Suite/Common/IrssComms/GenericMessageQueue.cs Modified: trunk/plugins/IR Server Suite/Common/IrssComms/Client.cs =================================================================== --- trunk/plugins/IR Server Suite/Common/IrssComms/Client.cs 2007-09-18 12:40:31 UTC (rev 936) +++ trunk/plugins/IR Server Suite/Common/IrssComms/Client.cs 2007-09-18 14:00:39 UTC (rev 937) @@ -31,7 +31,7 @@ volatile bool _processConnectionThread = false; volatile bool _connected = false; - GenericMessageQueue<IrssMessage> _messageQueue; + GenericPCQueue<IrssMessage> _messageQueue; ClientMessageSink _messageSink; @@ -93,7 +93,7 @@ _messageSink = messageSink; - _messageQueue = new GenericMessageQueue<IrssMessage>(new GenericMessageQueueSink<IrssMessage>(QueueMessageSink)); + _messageQueue = new GenericPCQueue<IrssMessage>(new GenericPCQueueSink<IrssMessage>(QueueMessageSink)); } #endregion Constructor Deleted: trunk/plugins/IR Server Suite/Common/IrssComms/GenericMessageQueue.cs =================================================================== --- trunk/plugins/IR Server Suite/Common/IrssComms/GenericMessageQueue.cs 2007-09-18 12:40:31 UTC (rev 936) +++ trunk/plugins/IR Server Suite/Common/IrssComms/GenericMessageQueue.cs 2007-09-18 14:00:39 UTC (rev 937) @@ -1,200 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; - -namespace IrssComms -{ - - #region Delegates - - /// <summary> - /// Delegate for MessageQueue sink. - /// </summary> - /// <param name="obj">Generic object to process.</param> - public delegate void GenericMessageQueueSink<T>(T obj); - - #endregion Delegates - - /// <summary> - /// Implements a thread-safe Producer/Consumer Queue for messages. - /// </summary> - public class GenericMessageQueue<T> : IDisposable - { - - #region Variables - - Thread _workerThread; - Queue<T> _queue; - object _queueLock; - EventWaitHandle _queueWaitHandle; - volatile bool _processQueue; - - GenericMessageQueueSink<T> _messageSink; - - #endregion Variables - - #region Constructor - - /// <summary> - /// Create a new MessageQueue. - /// </summary> - /// <param name="sink">Where to send dequeued messages.</param> - public GenericMessageQueue(GenericMessageQueueSink<T> sink) - { - if (sink == null) - throw new ArgumentNullException("sink"); - - _messageSink = sink; - - // Create locking and control mechanisms ... - _queueLock = new object(); - _queueWaitHandle = new AutoResetEvent(false); - - // Create FIFO message queue - _queue = new Queue<T>(); - } - - #endregion Constructor - - #region IDisposable - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - // Dispose managed resources ... - if (_processQueue) - Stop(); - - _workerThread = null; - - _queue.Clear(); - _queue = null; - - _queueLock = null; - - _queueWaitHandle.Close(); - } - - // Free native resources ... - - } - - #endregion IDisposable - - #region Implementation - - /// <summary> - /// Start processing the queue. - /// </summary> - public void Start() - { - if (_processQueue) - return; - - _processQueue = true; - - // Create the worker thread ... - _workerThread = new Thread(new ThreadStart(WorkerThread)); - _workerThread.IsBackground = true; - _workerThread.Name = "Message Queue"; - - _workerThread.Start(); - } - - /// <summary> - /// Stop processing the queue. - /// </summary> - public void Stop() - { - if (!_processQueue) - return; - - // Signal the worker thread to stop ... - _processQueue = false; - _queueWaitHandle.Set(); - - // Join the worker thread and wait for it to finish ... - if (_workerThread != null && _workerThread.IsAlive && !_workerThread.Join(1000)) - { - _workerThread.Abort(); - _workerThread.Join(); - } - - _workerThread = null; - } - - /// <summary> - /// Add a generic object to the queue. - /// </summary> - /// <param name="obj">Generic object to place in the queue.</param> - public void Enqueue(T obj) - { - if (obj == null) - throw new ArgumentNullException("obj"); - - lock (_queueLock) - _queue.Enqueue(obj); - - _queueWaitHandle.Set(); - } - - /// <summary> - /// Clears the queue of any messages. - /// </summary> - public void ClearQueue() - { - lock (_queueLock) - { - _queue.Clear(); - } - } - - /// <summary> - /// Queue processing worker thread. - /// </summary> - void WorkerThread() - { - try - { - T obj = default(T); - bool didDequeue; - - while (_processQueue) - { - didDequeue = false; - - lock (_queueLock) - { - if (_queue.Count > 0) - { - obj = _queue.Dequeue(); - didDequeue = true; - } - } - - if (didDequeue) - _messageSink(obj); - else - _queueWaitHandle.WaitOne(); - } - } - catch (ThreadAbortException threadAbortException) - { - Trace.WriteLine(threadAbortException.ToString()); - } - } - - #endregion Implementation - - } - -} Added: trunk/plugins/IR Server Suite/Common/IrssComms/GenericPCQueue.cs =================================================================== --- trunk/plugins/IR Server Suite/Common/IrssComms/GenericPCQueue.cs (rev 0) +++ trunk/plugins/IR Server Suite/Common/IrssComms/GenericPCQueue.cs 2007-09-18 14:00:39 UTC (rev 937) @@ -0,0 +1,200 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.Threading; + +namespace IrssComms +{ + + #region Delegates + + /// <summary> + /// Delegate for GenericPCQueue sink. + /// </summary> + /// <param name="obj">Generic object to process.</param> + public delegate void GenericPCQueueSink<T>(T obj); + + #endregion Delegates + + /// <summary> + /// Implements a thread-safe Producer/Consumer Queue for generics. + /// </summary> + public class GenericPCQueue<T> : IDisposable + { + + #region Variables + + Thread _workerThread; + Queue<T> _queue; + object _queueLock; + EventWaitHandle _queueWaitHandle; + volatile bool _processQueue; + + GenericPCQueueSink<T> _sink; + + #endregion Variables + + #region Constructor + + /// <summary> + /// Create a new MessageQueue. + /// </summary> + /// <param name="sink">Where to send dequeued messages.</param> + public GenericPCQueue(GenericPCQueueSink<T> sink) + { + if (sink == null) + throw new ArgumentNullException("sink"); + + _sink = sink; + + // Create locking and control mechanisms ... + _queueLock = new object(); + _queueWaitHandle = new AutoResetEvent(false); + + // Create FIFO generic queue + _queue = new Queue<T>(); + } + + #endregion Constructor + + #region IDisposable + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + // Dispose managed resources ... + if (_processQueue) + Stop(); + + _workerThread = null; + + _queue.Clear(); + _queue = null; + + _queueLock = null; + + _queueWaitHandle.Close(); + } + + // Free native resources ... + + } + + #endregion IDisposable + + #region Implementation + + /// <summary> + /// Start processing the queue. + /// </summary> + public void Start() + { + if (_processQueue) + return; + + _processQueue = true; + + // Create the worker thread ... + _workerThread = new Thread(new ThreadStart(WorkerThread)); + _workerThread.IsBackground = true; + _workerThread.Name = "IrssComms.GenericPCQueue"; + + _workerThread.Start(); + } + + /// <summary> + /// Stop processing the queue. + /// </summary> + public void Stop() + { + if (!_processQueue) + return; + + // Signal the worker thread to stop ... + _processQueue = false; + _queueWaitHandle.Set(); + + // Join the worker thread and wait for it to finish ... + if (_workerThread != null && _workerThread.IsAlive && !_workerThread.Join(1000)) + { + _workerThread.Abort(); + _workerThread.Join(); + } + + _workerThread = null; + } + + /// <summary> + /// Add a generic object to the queue. + /// </summary> + /// <param name="obj">Generic object to place in the queue.</param> + public void Enqueue(T obj) + { + if (obj == null) + throw new ArgumentNullException("obj"); + + lock (_queueLock) + _queue.Enqueue(obj); + + _queueWaitHandle.Set(); + } + + /// <summary> + /// Clears the queue of any messages. + /// </summary> + public void ClearQueue() + { + lock (_queueLock) + { + _queue.Clear(); + } + } + + /// <summary> + /// Queue processing worker thread. + /// </summary> + void WorkerThread() + { + try + { + T obj = default(T); + bool didDequeue; + + while (_processQueue) + { + didDequeue = false; + + lock (_queueLock) + { + if (_queue.Count > 0) + { + obj = _queue.Dequeue(); + didDequeue = true; + } + } + + if (didDequeue) + _sink(obj); + else + _queueWaitHandle.WaitOne(); + } + } + catch (ThreadAbortException threadAbortException) + { + Trace.WriteLine(threadAbortException.ToString()); + } + } + + #endregion Implementation + + } + +} Modified: trunk/plugins/IR Server Suite/Common/IrssComms/IrssComms.csproj =================================================================== --- trunk/plugins/IR Server Suite/Common/IrssComms/IrssComms.csproj 2007-09-18 12:40:31 UTC (rev 936) +++ trunk/plugins/IR Server Suite/Common/IrssComms/IrssComms.csproj 2007-09-18 14:00:39 UTC (rev 937) @@ -59,7 +59,7 @@ <Compile Include="Client.cs" /> <Compile Include="ClientManager.cs" /> <Compile Include="IrssMessage.cs" /> - <Compile Include="GenericMessageQueue.cs" /> + <Compile Include="GenericPCQueue.cs" /> <Compile Include="MessageManagerCombo.cs" /> <Compile Include="Server.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> Modified: trunk/plugins/IR Server Suite/Common/IrssComms/Server.cs =================================================================== --- trunk/plugins/IR Server Suite/Common/IrssComms/Server.cs 2007-09-18 12:40:31 UTC (rev 936) +++ trunk/plugins/IR Server Suite/Common/IrssComms/Server.cs 2007-09-18 14:00:39 UTC (rev 937) @@ -46,7 +46,7 @@ List<ClientManager> _clientManagers; - GenericMessageQueue<MessageManagerCombo> _messageQueue; + GenericPCQueue<MessageManagerCombo> _messageQueue; #endregion Variables @@ -63,7 +63,7 @@ _messageSink = messageSink; - _messageQueue = new GenericMessageQueue<MessageManagerCombo>(new GenericMessageQueueSink<MessageManagerCombo>(QueueMessageSink)); + _messageQueue = new GenericPCQueue<MessageManagerCombo>(new GenericPCQueueSink<MessageManagerCombo>(QueueMessageSink)); } #endregion Constructor Added: trunk/plugins/IR Server Suite/Input Service/Input Service.csproj =================================================================== --- trunk/plugins/IR Server Suite/Input Service/Input Service.csproj (rev 0) +++ trunk/plugins/IR Server Suite/Input Service/Input Service.csproj 2007-09-18 14:00:39 UTC (rev 937) @@ -0,0 +1,94 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{8ADDE1CB-2D23-4AB1-88B1-A241C60C16BA}</ProjectGuid> + <OutputType>WinExe</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>InputService</RootNamespace> + <AssemblyName>Input Service</AssemblyName> + <StartupObject>InputService.Program</StartupObject> + <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <PlatformTarget>AnyCPU</PlatformTarget> + <UseVSHostingProcess>false</UseVSHostingProcess> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> + <DebugSymbols>true</DebugSymbols> + <OutputPath>bin\x86\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <DebugType>full</DebugType> + <PlatformTarget>x86</PlatformTarget> + <ErrorReport>prompt</ErrorReport> + <TreatWarningsAsErrors>true</TreatWarningsAsErrors> + <UseVSHostingProcess>false</UseVSHostingProcess> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> + <OutputPath>bin\x86\Release\</OutputPath> + <DefineConstants> + </DefineConstants> + <DebugType>pdbonly</DebugType> + <PlatformTarget>x86</PlatformTarget> + <UseVSHostingProcess>false</UseVSHostingProcess> + <ErrorReport>prompt</ErrorReport> + <TreatWarningsAsErrors>true</TreatWarningsAsErrors> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Configuration.Install" /> + <Reference Include="System.Data" /> + <Reference Include="System.Management" /> + <Reference Include="System.ServiceProcess" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="InputService.cs"> + <SubType>Component</SubType> + </Compile> + <Compile Include="InputServiceInstaller.cs"> + <SubType>Component</SubType> + </Compile> + <Compile Include="Program.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\Common\IrssComms\IrssComms.csproj"> + <Project>{BCAFDF45-70DD-46FD-8B98-880DDA585AD2}</Project> + <Name>IrssComms</Name> + </ProjectReference> + <ProjectReference Include="..\Common\IrssUtils\IrssUtils.csproj"> + <Project>{CA15769C-232E-4CA7-94FD-206A06CA3ABB}</Project> + <Name>IrssUtils</Name> + </ProjectReference> + <ProjectReference Include="..\IR Server Plugins\IR Server Plugin Interface\IR Server Plugin Interface.csproj"> + <Project>{D8B3D28F-62CE-4CA7-86CE-B7EAD614A94C}</Project> + <Name>IR Server Plugin Interface</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project> \ No newline at end of file Added: trunk/plugins/IR Server Suite/Input Service/InputService.cs =================================================================== --- trunk/plugins/IR Server Suite/Input Service/InputService.cs (rev 0) +++ trunk/plugins/IR Server Suite/Input Service/InputService.cs 2007-09-18 14:00:39 UTC (rev 937) @@ -0,0 +1,1125 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Reflection; +using System.ServiceProcess; +using System.Text; +using System.Threading; +using System.Xml; + +using Microsoft.Win32; +using Microsoft.Win32.SafeHandles; + +using IRServerPluginInterface; +using IrssComms; +using IrssUtils; + +namespace InputService +{ + + #region Enumerations + + /// <summary> + /// Describes the operation mode of the IR Server. + /// </summary> + public enum IRServerMode + { + /// <summary> + /// Acts as a standard IR Server (Default). + /// </summary> + ServerMode = 0, + /// <summary> + /// Relays button presses to another IR Server. + /// </summary> + RelayMode = 1, + /// <summary> + /// Acts as a repeater for another IR Server's IR blasting. + /// </summary> + RepeaterMode = 2, + } + + #endregion Enumerations + + public class InputService : ServiceBase + { + + #region Constants + + static readonly string ConfigurationFile = Common.FolderAppData + "Input Service\\Input Service.xml"; + + #endregion Constants + + #region Variables + + List<ClientManager> _registeredClients; + List<ClientManager> _registeredRepeaters; + + Server _server = null; + Client _client = null; + + int _serverPort = 24000; + + IRServerMode _mode; + string _hostComputer; + + bool _registered = false; // Used for relay and repeater modes. + + string _pluginNameReceive = String.Empty; + IRServerPlugin _pluginReceive = null; + + string _pluginNameTransmit = String.Empty; + IRServerPlugin _pluginTransmit = null; + + #endregion Variables + + #region Constructor + + public InputService() + { + this.ServiceName = Program.ServiceName; + + //this.EventLog.Log = "Application"; + //this.AutoLog = true; + + this.CanHandlePowerEvent = true; + this.CanHandleSessionChangeEvent = false; + this.CanPauseAndContinue = false; + this.CanShutdown = true; + this.CanStop = true; + } + + #endregion Constructor + + #region Dispose + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + } + + #endregion Dispose + + #region Service Methods + + protected override void OnStart(string[] args) + { + // TODO: Change log level to info for release. + IrssLog.LogLevel = IrssLog.Level.Debug; + IrssLog.Open(Common.FolderIrssLogs + "Input Service.log"); + + try + { + IrssLog.Info("Starting IR Server ..."); + + LoadSettings(); + + // Load IR Plugins ... + _pluginReceive = null; + _pluginTransmit = null; + + if (String.IsNullOrEmpty(_pluginNameReceive) && String.IsNullOrEmpty(_pluginNameTransmit)) + { + IrssLog.Warn("No transmit or receive plugin loaded"); + } + else + { + if (String.IsNullOrEmpty(_pluginNameReceive)) + { + IrssLog.Warn("No receiver plugin loaded"); + } + else + { + _pluginReceive = Program.GetPlugin(_pluginNameReceive); + } + + if (_pluginNameTransmit.Equals(_pluginNameReceive, StringComparison.InvariantCultureIgnoreCase)) + { + _pluginTransmit = _pluginReceive; + IrssLog.Info("Using the same plugin for transmit and receive"); + } + else if (String.IsNullOrEmpty(_pluginNameTransmit)) + { + IrssLog.Warn("No transmit plugin loaded"); + } + else + { + _pluginTransmit = Program.GetPlugin(_pluginNameTransmit); + } + } + + switch (_mode) + { + case IRServerMode.ServerMode: + { + StartServer(); + + IrssLog.Info("Started in Server Mode"); + break; + } + + case IRServerMode.RelayMode: + { + if (StartRelay()) + IrssLog.Info("Started in Relay Mode"); + else + IrssLog.Error("Failed to start in Relay Mode"); + break; + } + + case IRServerMode.RepeaterMode: + { + if (StartRepeater()) + IrssLog.Info("Started in Repeater Mode"); + else + IrssLog.Error("Failed to start in Repeater Mode"); + break; + } + } + + // Start plugin(s) ... + if (_pluginReceive != null) + { + try + { + if (_pluginReceive.Start()) + IrssLog.Info("Receiver plugin started: \"{0}\"", _pluginNameReceive); + else + IrssLog.Error("Failed to start receive plugin: \"{0}\"", _pluginNameReceive); + } + catch (Exception ex) + { + IrssLog.Error("Failed to start receive plugin: \"{0}\"", _pluginNameReceive); + IrssLog.Error(ex.ToString()); + } + } + + if (!_pluginNameTransmit.Equals(_pluginNameReceive, StringComparison.InvariantCultureIgnoreCase)) + { + if (_pluginTransmit != null) + { + try + { + if (_pluginTransmit.Start()) + IrssLog.Info("Transmit plugin started: \"{0}\"", _pluginNameTransmit); + else + IrssLog.Error("Failed to start transmit plugin: \"{0}\"", _pluginNameTransmit); + } + catch (Exception ex) + { + IrssLog.Error("Failed to start transmit plugin: \"{0}\"", _pluginNameTransmit); + IrssLog.Error(ex.ToString()); + } + } + } + + if (_pluginReceive != null) + { + if (_pluginReceive is IRemoteReceiver) + (_pluginReceive as IRemoteReceiver).RemoteCallback += new RemoteHandler(RemoteHandlerCallback); + + if (_pluginReceive is IKeyboardReceiver) + (_pluginReceive as IKeyboardReceiver).KeyboardCallback += new KeyboardHandler(KeyboardHandlerCallback); + + if (_pluginReceive is IMouseReceiver) + (_pluginReceive as IMouseReceiver).MouseCallback += new MouseHandler(MouseHandlerCallback); + } + + IrssLog.Info("IR Server started"); + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + } + } + + protected override void OnStop() + { + IrssLog.Info("Stopping IR Server ..."); + + if (_mode == IRServerMode.ServerMode) + { + IrssMessage message = new IrssMessage(MessageType.ServerShutdown, MessageFlags.Notify); + SendToAll(message); + } + + if (_pluginReceive != null) + { + if (_pluginReceive is IRemoteReceiver) + (_pluginReceive as IRemoteReceiver).RemoteCallback -= new RemoteHandler(RemoteHandlerCallback); + + if (_pluginReceive is IKeyboardReceiver) + (_pluginReceive as IKeyboardReceiver).KeyboardCallback -= new KeyboardHandler(KeyboardHandlerCallback); + + if (_pluginReceive is IMouseReceiver) + (_pluginReceive as IMouseReceiver).MouseCallback -= new MouseHandler(MouseHandlerCallback); + } + + // Stop Plugin(s) + try + { + if (_pluginReceive != null) + _pluginReceive.Stop(); + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + } + try + { + if (_pluginTransmit != null && _pluginTransmit != _pluginReceive) + _pluginTransmit.Stop(); + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + } + + // Stop Server + try + { + switch (_mode) + { + case IRServerMode.ServerMode: + StopServer(); + break; + + case IRServerMode.RelayMode: + StopRelay(); + break; + + case IRServerMode.RepeaterMode: + StopRepeater(); + break; + } + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + } + + IrssLog.Close(); + } + + protected override void OnShutdown() + { + OnStop(); + } + + protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus) + { + switch (powerStatus) + { + case PowerBroadcastStatus.Suspend: + IrssLog.Info("Entering standby ..."); + + if (_pluginReceive != null) + _pluginReceive.Suspend(); + + if (_pluginTransmit != null && _pluginTransmit != _pluginReceive) + _pluginTransmit.Suspend(); + + // Inform clients ... + if (_mode == IRServerMode.ServerMode) + { + IrssMessage message = new IrssMessage(MessageType.ServerShutdown, MessageFlags.Notify); + SendToAll(message); + } + break; + + case PowerBroadcastStatus.ResumeAutomatic: + case PowerBroadcastStatus.ResumeCritical: + case PowerBroadcastStatus.ResumeSuspend: + IrssLog.Info("Resume from standby ..."); + + if (_pluginReceive != null) + _pluginReceive.Resume(); + + if (_pluginTransmit != null && _pluginTransmit != _pluginReceive) + _pluginTransmit.Resume(); + + // TODO: Inform clients ? + break; + } + + return true; + } + + #region Unused + + protected override void OnPause() + { + } + + protected override void OnContinue() + { + } + + protected override void OnSessionChange(SessionChangeDescription changeDescription) + { + switch (changeDescription.Reason) + { + case SessionChangeReason.SessionLogon: + break; + + case SessionChangeReason.SessionLogoff: + break; + } + } + + protected override void OnCustomCommand(int command) + { + switch (command) + { + case 128: + break; + } + } + + #endregion Unused + + #endregion Service Methods + + void StartServer() + { + if (_server != null) + return; + + // Initialize registered client lists ... + _registeredClients = new List<ClientManager>(); + _registeredRepeaters = new List<ClientManager>(); + + ServerMessageSink sink = new ServerMessageSink(ServerReceivedMessage); + _server = new Server(_serverPort, sink); + + _server.Start(); + } + void StopServer() + { + if (_server == null) + return; + + _server.Stop(); + _server = null; + + _registeredClients.Clear(); + _registeredClients = null; + + _registeredRepeaters.Clear(); + _registeredRepeaters = null; + } + + void CommsFailure(object obj) + { + Exception ex = obj as Exception; + + if (ex != null) + IrssLog.Error("Communications failure: {0}", ex.Message); + else + IrssLog.Error("Communications failure"); + + StopClient(); + } + void Connected(object obj) + { + IrssLog.Info("Connected to another server"); + + if (_mode == IRServerMode.RepeaterMode) + { + IrssMessage message = new IrssMessage(MessageType.RegisterRepeater, MessageFlags.Request); + _client.Send(message); + } + } + void Disconnected(object obj) + { + IrssLog.Warn("Communications with other server has been lost"); + + Thread.Sleep(1000); + } + + bool StartClient() + { + if (_client != null) + return false; + + ClientMessageSink sink = new ClientMessageSink(ClientReceivedMessage); + + IPAddress serverAddress = Client.GetIPFromName(_hostComputer); + + _client = new Client(serverAddress, 24000, sink); + _client.CommsFailureCallback = new WaitCallback(CommsFailure); + _client.ConnectCallback = new WaitCallback(Connected); + _client.DisconnectCallback = new WaitCallback(Disconnected); + + if (_client.Start()) + { + return true; + } + else + { + _client = null; + return false; + } + } + void StopClient() + { + if (_client == null) + return; + + _client.Stop(); + _client = null; + } + + bool StartRelay() + { + try + { + StartServer(); + StartClient(); + + return true; + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + return false; + } + } + void StopRelay() + { + try + { + StopServer(); + StopClient(); + } + catch { } + } + + bool StartRepeater() + { + try + { + StartServer(); + StartClient(); + + return true; + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + return false; + } + } + void StopRepeater() + { + try + { + if (_registered) + { + _registered = false; + + IrssMessage message = new IrssMessage(MessageType.UnregisterRepeater, MessageFlags.Request); + _client.Send(message); + } + + StopServer(); + StopClient(); + } + catch { } + } + + void RemoteHandlerCallback(string keyCode) + { + IrssLog.Debug("Remote Event: {0}", keyCode); + + byte[] bytes = Encoding.ASCII.GetBytes(keyCode); + + switch (_mode) + { + case IRServerMode.ServerMode: + { + IrssMessage message = new IrssMessage(MessageType.RemoteEvent, MessageFlags.Notify, bytes); + SendToAll(message); + break; + } + + case IRServerMode.RelayMode: + { + IrssMessage message = new IrssMessage(MessageType.ForwardRemoteEvent, MessageFlags.Request, bytes); + _client.Send(message); + break; + } + + case IRServerMode.RepeaterMode: + { + IrssLog.Debug("Remote event ignored, IR Server is in Repeater Mode."); + break; + } + } + } + void KeyboardHandlerCallback(int vKey, bool keyUp) + { + IrssLog.Debug("Keyboard Event: {0}, keyUp: {1}", vKey, keyUp); + + byte[] bytes = new byte[8]; + BitConverter.GetBytes(vKey).CopyTo(bytes, 0); + BitConverter.GetBytes(keyUp).CopyTo(bytes, 4); + + switch (_mode) + { + case IRServerMode.ServerMode: + { + IrssMessage message = new IrssMessage(MessageType.KeyboardEvent, MessageFlags.Notify, bytes); + SendToAll(message); + break; + } + + case IRServerMode.RelayMode: + { + IrssMessage message = new IrssMessage(MessageType.ForwardKeyboardEvent, MessageFlags.Request, bytes); + _client.Send(message); + break; + } + + case IRServerMode.RepeaterMode: + { + IrssLog.Debug("Keyboard event ignored, IR Server is in Repeater Mode."); + break; + } + } + } + void MouseHandlerCallback(int deltaX, int deltaY, int buttons) + { + IrssLog.Debug("Mouse Event - deltaX: {0}, deltaY: {1}, buttons: {2}", deltaX, deltaY, buttons); + + byte[] bytes = new byte[12]; + BitConverter.GetBytes(deltaX).CopyTo(bytes, 0); + BitConverter.GetBytes(deltaY).CopyTo(bytes, 4); + BitConverter.GetBytes(buttons).CopyTo(bytes, 8); + + switch (_mode) + { + case IRServerMode.ServerMode: + { + IrssMessage message = new IrssMessage(MessageType.MouseEvent, MessageFlags.Notify, bytes); + SendToAll(message); + break; + } + + case IRServerMode.RelayMode: + { + IrssMessage message = new IrssMessage(MessageType.ForwardMouseEvent, MessageFlags.Request, bytes); + _client.Send(message); + break; + } + + case IRServerMode.RepeaterMode: + { + IrssLog.Debug("Mouse event ignored, IR Server is in Repeater Mode."); + break; + } + } + } + + void SendToAll(IrssMessage message) + { + IrssLog.Debug("SendToAll({0}, {1})", message.Type, message.Flags); + + List<ClientManager> unregister = new List<ClientManager>(); + + lock (_registeredClients) + { + foreach (ClientManager client in _registeredClients) + { + if (!_server.Send(client, message)) + { + IrssLog.Warn("Failed to send message to a client, unregistering client"); + + // If a message doesn't get through then unregister that client + unregister.Add(client); + } + } + + // Unregistering clients must be done as a two part process because otherwise the + // foreach statement above would fail if you modified the _registeredClients list + // while enumerating it. + foreach (ClientManager client in unregister) + { + UnregisterClient(client); + } + } + } + void SendToAllExcept(ClientManager exceptClient, IrssMessage message) + { + IrssLog.Debug("SendToAllExcept({0}, {1})", message.Type, message.Flags); + + List<ClientManager> unregister = new List<ClientManager>(); + + lock (_registeredClients) + { + foreach (ClientManager client in _registeredClients) + { + if (client == exceptClient) + continue; + + if (!_server.Send(client, message)) + { + IrssLog.Warn("Failed to send message to a client, unregistering client"); + + // If a message doesn't get through then unregister that client + unregister.Add(client); + } + } + + // Unregistering clients must be done as a two part process because otherwise the + // foreach statement above would fail if you modified the _registeredClients list + // while enumerating it. + foreach (ClientManager client in unregister) + { + UnregisterClient(client); + } + } + } + void SendTo(ClientManager receiver, IrssMessage message) + { + IrssLog.Debug("SendTo({0}, {1})", message.Type, message.Flags); + + if (!_server.Send(receiver, message)) + { + IrssLog.Warn("Failed to send message to a client, unregistering client"); + + // If a message doesn't get through then unregister that client + UnregisterClient(receiver); + } + } + void SendToRepeaters(IrssMessage message) + { + IrssLog.Debug("SendToRepeaters({0}, {1})", message.Type, message.Flags); + + List<ClientManager> unregister = new List<ClientManager>(); + + lock (_registeredRepeaters) + { + foreach (ClientManager client in _registeredRepeaters) + { + if (!_server.Send(client, message)) + { + IrssLog.Warn("Failed to send message to a repeater, unregistering repeater"); + + // If a message doesn't get through then unregister that repeater + unregister.Add(client); + } + } + + // Unregistering repeaters must be done as a two part process because otherwise the + // foreach statement above would fail if you modified the _registeredRepeaters list + // while enumerating it. + foreach (ClientManager repeater in unregister) + { + UnregisterRepeater(repeater); + } + } + } + + bool RegisterClient(ClientManager addClient) + { + lock (_registeredClients) + { + if (!_registeredClients.Contains(addClient)) + _registeredClients.Add(addClient); + } + + IrssLog.Info("Registered a client"); + return true; + } + bool UnregisterClient(ClientManager removeClient) + { + lock (_registeredClients) + { + if (!_registeredClients.Contains(removeClient)) + return false; + + _registeredClients.Remove(removeClient); + } + + IrssLog.Info("Unregistered a client"); + return true; + } + + bool RegisterRepeater(ClientManager addRepeater) + { + lock (_registeredRepeaters) + { + if (!_registeredRepeaters.Contains(addRepeater)) + _registeredRepeaters.Add(addRepeater); + } + + IrssLog.Info("Registered a repeater"); + return true; + } + bool UnregisterRepeater(ClientManager removeRepeater) + { + lock (_registeredRepeaters) + { + if (!_registeredRepeaters.Contains(removeRepeater)) + return false; + + _registeredRepeaters.Remove(removeRepeater); + } + + IrssLog.Info("Unregistered a repeater"); + return true; + } + + bool BlastIR(byte[] data) + { + try + { + IrssLog.Debug("Blast IR"); + + if (_pluginTransmit == null || !(_pluginTransmit is ITransmitIR)) + return false; + + string port = "Default"; + + int portLen = BitConverter.ToInt32(data, 0); + if (portLen > 0) + port = Encoding.ASCII.GetString(data, 4, portLen); + + byte[] codeData = new byte[data.Length - (4 + portLen)]; + Array.Copy(data, 4 + portLen, codeData, 0, codeData.Length); + + return (_pluginTransmit as ITransmitIR).Transmit(port, codeData); + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + return false; + } + } + LearnStatus LearnIR(out byte[] data) + { + IrssLog.Debug("Learn IR"); + + data = null; + + if (_pluginTransmit == null) + { + IrssLog.Debug("No transmit plugin loaded, can't learn"); + return LearnStatus.Failure; + } + else if (!(_pluginTransmit is ILearnIR)) + { + IrssLog.Debug("Active transmit plugin doesn't support learn"); + return LearnStatus.Failure; + } + + Thread.Sleep(250); + + LearnStatus status = LearnStatus.Failure; + + try + { + status = (_pluginTransmit as ILearnIR).Learn(out data); + switch (status) + { + case LearnStatus.Success: + IrssLog.Info("Learn IR success"); + break; + + case LearnStatus.Failure: + IrssLog.Error("Failed to learn IR Code"); + break; + + case LearnStatus.Timeout: + IrssLog.Warn("IR Code learn timed out"); + break; + } + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + } + + return status; + } + + void ServerReceivedMessage(MessageManagerCombo combo) + { + IrssLog.Debug("Server message received: {0}, {1}", combo.Message.Type, combo.Message.Flags); + + try + { + switch (combo.Message.Type) + { + case MessageType.ForwardRemoteEvent: + if (_mode == IRServerMode.RelayMode) + { + IrssMessage forward = new IrssMessage(MessageType.ForwardRemoteEvent, MessageFlags.Request, combo.Message.DataAsBytes); + _client.Send(forward); + } + else + { + IrssMessage forward = new IrssMessage(MessageType.RemoteEvent, MessageFlags.Notify, combo.Message.DataAsBytes); + SendToAllExcept(combo.Manager, forward); + } + break; + + case MessageType.ForwardKeyboardEvent: + if (_mode == IRServerMode.RelayMode) + { + IrssMessage forward = new IrssMessage(MessageType.ForwardKeyboardEvent, MessageFlags.Request, combo.Message.DataAsBytes); + _client.Send(forward); + } + else + { + IrssMessage forward = new IrssMessage(MessageType.KeyboardEvent, MessageFlags.Notify, combo.Message.DataAsBytes); + SendToAllExcept(combo.Manager, forward); + } + break; + + case MessageType.ForwardMouseEvent: + if (_mode == IRServerMode.RelayMode) + { + IrssMessage forward = new IrssMessage(MessageType.ForwardMouseEvent, MessageFlags.Request, combo.Message.DataAsBytes); + _client.Send(forward); + } + else + { + IrssMessage forward = new IrssMessage(MessageType.MouseEvent, MessageFlags.Notify, combo.Message.DataAsBytes); + SendToAllExcept(combo.Manager, forward); + } + break; + + case MessageType.BlastIR: + { + IrssMessage response = new IrssMessage(MessageType.BlastIR, MessageFlags.Response); + + if (_mode == IRServerMode.RelayMode) + { + response.Flags |= MessageFlags.Failure; + } + else + { + if (_registeredRepeaters.Count > 0) + SendToRepeaters(combo.Message); + + if (BlastIR(combo.Message.DataAsBytes)) + response.Flags |= MessageFlags.Success; + else + response.Flags |= MessageFlags.Failure; + } + + if ((combo.Message.Flags & MessageFlags.ForceNotRespond) != MessageFlags.ForceNotRespond) + SendTo(combo.Manager, response); + + break; + } + + case MessageType.LearnIR: + { + IrssMessage response = new IrssMessage(MessageType.LearnIR, MessageFlags.Response); + + if (_mode == IRServerMode.RelayMode) + { + response.Flags |= MessageFlags.Failure; + } + else + { + byte[] bytes = null; + + LearnStatus status = LearnIR(out bytes); + + switch (status) + { + case LearnStatus.Success: + response.Flags |= MessageFlags.Success; + response.DataAsBytes = bytes; + break; + + case LearnStatus.Failure: + response.Flags |= MessageFlags.Failure; + break; + + case LearnStatus.Timeout: + response.Flags |= MessageFlags.Timeout; + break; + } + } + + SendTo(combo.Manager, response); + break; + } + + case MessageType.ServerShutdown: + if ((combo.Message.Flags & MessageFlags.Request) == MessageFlags.Request) + { + IrssLog.Info("Shutdown command received"); + Stop(); + } + + break; + + case MessageType.Ping: + { + IrssMessage response = new IrssMessage(MessageType.Echo, MessageFlags.Response, combo.Message.DataAsBytes); + SendTo(combo.Manager, response); + break; + } + + case MessageType.RegisterClient: + { + IrssMessage response = new IrssMessage(MessageType.RegisterClient, MessageFlags.Response); + + if (RegisterClient(combo.Manager)) + { + IRServerInfo irServerInfo = new IRServerInfo(); + + if (_pluginReceive != null) + irServerInfo.CanReceive = true; + + if (_pluginTransmit != null) + { + irServerInfo.CanLearn = (_pluginTransmit is ILearnIR); + irServerInfo.CanTransmit = true; + irServerInfo.Ports = (_pluginTransmit as ITransmitIR).AvailablePorts; + } + + response.DataAsBytes = irServerInfo.ToBytes(); + response.Flags |= MessageFlags.Success; + } + else + { + response.Flags |= MessageFlags.Failure; + } + + SendTo(combo.Manager, response); + break; + } + + case MessageType.UnregisterClient: + UnregisterClient(combo.Manager); + break; + + case MessageType.RegisterRepeater: + { + IrssMessage response = new IrssMessage(MessageType.RegisterRepeater, MessageFlags.Response); + + if (RegisterRepeater(combo.Manager)) + response.Flags |= MessageFlags.Success; + else + response.Flags |= MessageFlags.Failure; + + SendTo(combo.Manager, response); + break; + } + + case MessageType.UnregisterRepeater: + UnregisterRepeater(combo.Manager); + break; + } + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + IrssMessage response = new IrssMessage(MessageType.Error, MessageFlags.Notify, ex.Message); + SendTo(combo.Manager, response); + } + } + void ClientReceivedMessage(IrssMessage received) + { + IrssLog.Debug("Client message received: {0}, {1}", received.Type, received.Flags); + + try + { + switch (received.Type) + { + case MessageType.RegisterClient: + if ((received.Flags & MessageFlags.Response) == MessageFlags.Response) + { + if ((received.Flags & MessageFlags.Success) == MessageFlags.Success) + { + IrssLog.Info("Registered with host server"); + _registered = true; + } + else + { + IrssLog.Warn("Host server refused registration"); + _registered = false; + } + } + break; + + case MessageType.ServerShutdown: + if ((received.Flags & MessageFlags.Notify) == MessageFlags.Notify) + { + IrssLog.Warn("Host server has shut down"); + _registered = false; + } + break; + } + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + IrssMessage response = new IrssMessage(MessageType.Error, MessageFlags.Notify, ex.Message); + _client.Send(response); + } + } + + void LoadSettings() + { + try + { + XmlDocument doc = new XmlDocument(); + doc.Load(ConfigurationFile); + + _mode = (IRServerMode)Enum.Parse(typeof(IRServerMode), doc.DocumentElement.Attributes["Mode"].Value, true); + _hostComputer = doc.DocumentElement.Attributes["HostComputer"].Value; + _pluginNameReceive = doc.DocumentElement.Attributes["PluginReceive"].Value; + _pluginNameTransmit = doc.DocumentElement.Attributes["PluginTransmit"].Value; + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + + _mode = IRServerMode.ServerMode; + _hostComputer = String.Empty; + _pluginNameReceive = String.Empty; + _pluginNameTransmit = String.Empty; + } + } + void SaveSettings() + { + try + { + XmlTextWriter writer = new XmlTextWriter(ConfigurationFile, System.Text.Encoding.UTF8); + writer.Formatting = Formatting.Indented; + writer.Indentation = 1; + writer.IndentChar = (char)9; + writer.WriteStartDocument(true); + writer.WriteStartElement("settings"); // <settings> + + writer.WriteAttributeString("Mode", Enum.GetName(typeof(IRServerMode), _mode)); + writer.WriteAttributeString("HostComputer", _hostComputer); + writer.WriteAttributeString("PluginReceive", _pluginNameReceive); + writer.WriteAttributeString("PluginTransmit", _pluginNameTransmit); + + writer.WriteEndElement(); // </settings> + writer.WriteEndDocument(); + writer.Close(); + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + } + } + + } + +} Added: trunk/plugins/IR Server Suite/Input Service/InputServiceInstaller.cs =================================================================== --- trunk/plugins/IR Server Suite/Input Service/InputServiceInstaller.cs (rev 0) +++ trunk/plugins/IR Server Suite/Input Service/InputServiceInstaller.cs 2007-09-18 14:00:39 UTC (rev 937) @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Configuration.Install; +using System.Diagnostics; +using System.Management; +using System.ServiceProcess; + +namespace InputService +{ + + [RunInstaller(true)] + public class InputServiceInstaller : Installer + { + + public InputServiceInstaller() + { + //this.Committing += new InstallEventHandler(InputServiceInstaller_Committing); + this.AfterInstall += new InstallEventHandler(InputServiceInstaller_AfterInstall); + + ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller(); + ServiceInstaller serviceInstaller = new ServiceInstaller(); + + // Service Account Information + serviceProcessInstaller.Account = ServiceAccount.LocalSystem; + serviceProcessInstaller.Username = null; + serviceProcessInstaller.Password = null; + + // Service Information + serviceInstaller.ServiceName = Program.ServiceName; + serviceInstaller.DisplayName = Program.ServiceDisplayName; + serviceInstaller.Description = Program.ServiceDescription; + serviceInstaller.StartType = ServiceStartMode.Automatic; + + this.Installers.Add(serviceProcessInstaller); + this.Installers.Add(serviceInstaller); + } + + /// <summary> + /// Code to execute after the install has completed. + /// </summary> + void InputServiceInstaller_AfterInstall(object sender, InstallEventArgs e) + { + // Start the service ... + using (ServiceController serviceController = new ServiceController(Program.ServiceName)) + serviceController.Start(); + } + + /// <summary> + /// Used to set the "Allow service to interact with the desktop" setting. + /// </summary> + void InputServiceInstaller_Committing(object sender, InstallEventArgs e) + { + ManagementBaseObject InParam = null; + ManagementBaseObject OutParam = null; + + try + { + ConnectionOptions coOptions = new ConnectionOptions(); + coOptions.Impersonation = ImpersonationLevel.Impersonate; + + ManagementScope mgmtScope = new ManagementScope(@"root\CIMV2", coOptions); + mgmtScope.Connect(); + + string path = string.Format("Win32_Service.Name='{0}'", Program.ServiceName); + + using (ManagementObject wmiService = new ManagementObject(path)) + { + InParam = wmiService.GetMethodParameters("Change"); + InParam["DesktopInteract"] = true; + OutParam = wmiService.InvokeMethod("Change", InParam, null); + } + } + catch (Exception ex) + { + Trace.WriteLine(ex.ToString()); + } + finally + { + if (InParam != null) + InParam.Dispose(); + + if (OutParam != null) + OutParam.Dispose(); + } + } + + } + +} Added: trunk/plugins/IR Server Suite/Input Service/Program.cs =================================================================== --- trunk/plugins/IR Server Suite/Input Service/Program.cs (rev 0) +++ trunk/plugins/IR Server Suite/Input Service/Program.cs 2007-09-18 14:00:39 UTC (rev 937) @@ -0,0 +1,134 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Configuration.Install; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.ServiceProcess; +using System.Text; + +using Microsoft.Win32; + +using IrssUtils; +using IRServerPluginInterface; + +namespace InputService +{ + + static class Program + { + + #region Constants + + public const string ServiceName = "MPInputService"; + public const string ServiceDisplayName = "MediaPortal Input Service"; + public const string ServiceDescription = "Provides access to input devices"; + + #endregion Constants + + static void Main(string[] args) + { + if (args.Length >= 1) + { + TransactedInstaller transactedInstaller = new TransactedInstaller(); + InputServiceInstaller inputServiceInstaller = new InputServiceInstaller(); + transactedInstaller.Installers.Add(inputServiceInstaller); + + String path = String.Format("/assemblypath={0}", Assembly.GetExecutingAssembly().Location); + String[] cmdline = { path }; + + InstallContext installContext = new InstallContext(String.Empty, cmdline); + transactedInstaller.Context = installContext; + + if (args[0].Equals("/install", System.StringComparison.InvariantCultureIgnoreCase)) + transactedInstaller.Install(new Hashtable()); + else if (args[0].Equals("/uninstall", System.StringComparison.InvariantCultureIgnoreCase)) + transactedInstaller.Uninstall(null); + + return; + } + + InputService inputService = new InputService(); + ServiceBase.Run(inputService); + } + + /// <summary> + /// Retreives a list of available IR Server plugins. + /// </summary> + /// <returns>Array of plugin instances.</returns> + internal static IRServerPlugin[] AvailablePlugins() + { + try + { + List<IRServerPlugin> plugins = new List<IRServerPlugin>(); + + string installFolder = SystemRegistry.GetInstallFolder(); + if (String.IsNullOrEmpty(installFolder)) + return null; + + string[] files = Directory.GetFiles(installFolder + "\\IR Server Plugins\\", "*.dll", SearchOption.TopDirectoryOnly); + + foreach (string file in files) + { + try + { + Assembly assembly = Assembly.LoadFrom(file); + + Type[] types = assembly.GetExportedTypes(); + + foreach (Type type in types) + { + if (type.IsClass && !type.IsAbstract && type.IsSubclassOf(typeof(IRServerPlugin))) + { + IRServerPlugin plugin = (IRServerPlugin)Activator.CreateInstance(type); + if (plugin == null) + continue; + + plugins.Add(plugin); + } + } + } + catch (BadImageFormatException) + { + // Ignore Bad Image Format Exceptions, just keep checking for IR Server Plugins + } + catch (Exception ex) + { + Trace.WriteLine(ex.ToString()); + } + } + + return plugins.ToArray(); + } + catch (Exception ex) + { + Trace.WriteLine(ex.ToString()); + return null; + } + } + + /// <summary> + /// Retreives a plugin instance given the plugin name. + /// </summary> + /// <param name="pluginName">Name of plugin to instantiate.</param> + /// <returns>Plugin instance.</returns> + internal static IRServerPlugin GetPlugin(string pluginName) + { + if (String.IsNullOrEmpty(pluginName)) + throw new ArgumentNullException("pluginName"); + + IRServerPlugin[] serverPlugins = AvailablePlugins(); + if (serverPlugins == null) + throw new ApplicationException("No available plugins found."); + + foreach (IRServerPlugin plugin in serverPlugins) + if (plugin.Name.Equals(pluginName, StringComparison.InvariantCultureIgnoreCase)) + return plugin; + + return null; + } + + } + +} Added: trunk/plugins/IR Server Suite/Input Service/Properties/AssemblyInfo.cs =================================================================== --- trunk/plugins/IR Server Suite/Input Service/Properties/AssemblyInfo.cs (rev 0) +++ trunk/plugins/IR Server Suite/Input Service/Properties/AssemblyInfo.cs 2007-09-18 14:00:39 UTC (rev 937) @@ -0,0 +1,36 @@ +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Input Service")] +[assembly: AssemblyDescription("MediaPortal Input Service")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("and-81")] +[assembly: AssemblyProduct("MediaPortal Input Service")] +[assembly: AssemblyCopyright("Aaron Dinnage")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f32fa19c-ea93-408e-b438-6aa36862a20e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.3.4")] +[assembly: AssemblyFileVersion("1.0.3.4")] + +[assembly: CLSCompliant(true)] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |