From: <an...@us...> - 2007-10-05 15:41:57
|
Revision: 977 http://mp-plugins.svn.sourceforge.net/mp-plugins/?rev=977&view=rev Author: and-81 Date: 2007-10-05 08:41:56 -0700 (Fri, 05 Oct 2007) Log Message: ----------- Added Paths: ----------- trunk/plugins/IR Server Suite/Input Service/Input Service/ trunk/plugins/IR Server Suite/Input Service/Input Service/Icon.ico trunk/plugins/IR Server Suite/Input Service/Input Service/Input Service.csproj trunk/plugins/IR Server Suite/Input Service/Input Service/InputService.cs trunk/plugins/IR Server Suite/Input Service/Input Service/InputServiceInstaller.cs trunk/plugins/IR Server Suite/Input Service/Input Service/Program.cs trunk/plugins/IR Server Suite/Input Service/Input Service/Properties/ trunk/plugins/IR Server Suite/Input Service/Input Service/Properties/AssemblyInfo.cs trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/ trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/Advanced.Designer.cs trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/Advanced.cs trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/Advanced.resx trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/Config.Designer.cs trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/Config.cs trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/Config.resx trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/Configuration.csproj trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/Icon.ico trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/Program.cs trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/Properties/ trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/Properties/AssemblyInfo.cs trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/SourceGrid/ trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/SourceGrid/DevAge.Core.dll trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/SourceGrid/DevAge.Windows.Forms.dll trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/SourceGrid/SourceGrid.License.txt trunk/plugins/IR Server Suite/Input Service/Input Service Configuration/SourceGrid/SourceGrid.dll Removed Paths: ------------- trunk/plugins/IR Server Suite/Input Service/Icon.ico 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 Deleted: trunk/plugins/IR Server Suite/Input Service/Icon.ico =================================================================== (Binary files differ) Added: trunk/plugins/IR Server Suite/Input Service/Input Service/Icon.ico =================================================================== (Binary files differ) Property changes on: trunk/plugins/IR Server Suite/Input Service/Input Service/Icon.ico ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/plugins/IR Server Suite/Input Service/Input Service/Input Service.csproj =================================================================== --- trunk/plugins/IR Server Suite/Input Service/Input Service/Input Service.csproj (rev 0) +++ trunk/plugins/IR Server Suite/Input Service/Input Service/Input Service.csproj 2007-10-05 15:41:56 UTC (rev 977) @@ -0,0 +1,102 @@ +<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> + <ApplicationIcon>Icon.ico</ApplicationIcon> + </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>none</DebugType> + <PlatformTarget>x86</PlatformTarget> + <UseVSHostingProcess>false</UseVSHostingProcess> + <ErrorReport>prompt</ErrorReport> + <TreatWarningsAsErrors>true</TreatWarningsAsErrors> + <Optimize>true</Optimize> + </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> + <ItemGroup> + <Content Include="Icon.ico" /> + </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> + --> + <PropertyGroup> + <PostBuildEvent>copy "*.*" "\MediaPortal Development\Plugin Releases\IR Server Suite\$(ProjectName)\"</PostBuildEvent> + </PropertyGroup> +</Project> \ No newline at end of file Added: trunk/plugins/IR Server Suite/Input Service/Input Service/InputService.cs =================================================================== --- trunk/plugins/IR Server Suite/Input Service/Input Service/InputService.cs (rev 0) +++ trunk/plugins/IR Server Suite/Input Service/Input Service/InputService.cs 2007-10-05 15:41:56 UTC (rev 977) @@ -0,0 +1,1474 @@ +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; + Client _client; + + IRServerMode _mode; + string _hostComputer; + + bool _registered; // Used for relay and repeater modes. + + string[] _pluginNameReceive; + IRServerPluginBase[] _pluginReceive; + + string _pluginNameTransmit; + IRServerPluginBase _pluginTransmit; + + #endregion Variables + + #region Constructor / Destructor + + 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 / Destructor + + #region IDisposable + + protected override void Dispose(bool disposing) + { + try + { + if (disposing) + { + if (_server != null) + _server.Dispose(); + + if (_client != null) + _client.Dispose(); + } + } + finally + { + base.Dispose(disposing); + } + } + + #endregion IDisposable + + #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 (_pluginNameReceive == null && String.IsNullOrEmpty(_pluginNameTransmit)) + { + IrssLog.Warn("No transmit or receive plugins loaded"); + } + else + { + if (_pluginNameReceive == null) + { + IrssLog.Warn("No receiver plugins loaded"); + } + else + { + List<IRServerPluginBase> plugins = new List<IRServerPluginBase>(_pluginNameReceive.Length); + + for (int index = 0; index < _pluginNameReceive.Length; index++) + { + string pluginName = _pluginNameReceive[index]; + + IRServerPluginBase plugin = Program.GetPlugin(pluginName); + + if (plugin == null) + { + IrssLog.Warn("Receiver plugin not found: {0}", pluginName); + } + else + { + plugins.Add(plugin); + + if (!String.IsNullOrEmpty(_pluginNameTransmit) && plugin.Name.Equals(_pluginNameTransmit)) + _pluginTransmit = plugin; + } + } + + _pluginReceive = plugins.ToArray(); + } + + if (String.IsNullOrEmpty(_pluginNameTransmit)) + { + IrssLog.Warn("No transmit plugin loaded"); + } + else if (_pluginTransmit == null) + { + _pluginTransmit = Program.GetPlugin(_pluginNameTransmit); + } + } + + // Mode select ... + 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) ... + + bool startedTransmit = false; + + if (_pluginReceive != null) + { + foreach (IRServerPluginBase plugin in _pluginReceive) + { + try + { + if (plugin.Start()) + { + IRemoteReceiver remoteReceiver = plugin as IRemoteReceiver; + if (remoteReceiver != null) + remoteReceiver.RemoteCallback += new RemoteHandler(RemoteHandlerCallback); + + IKeyboardReceiver keyboardReceiver = plugin as IKeyboardReceiver; + if (keyboardReceiver != null) + keyboardReceiver.KeyboardCallback += new KeyboardHandler(KeyboardHandlerCallback); + + IMouseReceiver mouseReceiver = plugin as IMouseReceiver; + if (mouseReceiver != null) + mouseReceiver.MouseCallback += new MouseHandler(MouseHandlerCallback); + + if (plugin.Name.Equals(_pluginTransmit.Name)) + { + startedTransmit = true; + IrssLog.Info("Transmit and Receive plugin started: \"{0}\"", plugin.Name); + } + else + { + IrssLog.Info("Receiver plugin started: \"{0}\"", plugin.Name); + } + } + else + { + IrssLog.Error("Failed to start receive plugin: \"{0}\"", plugin.Name); + } + } + catch (Exception ex) + { + IrssLog.Error("Failed to start receive plugin: \"{0}\"", plugin.Name); + IrssLog.Error(ex.ToString()); + } + } + } + + if (_pluginTransmit != null && !startedTransmit) + { + 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()); + } + } + + + 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); + } + + // Stop Plugin(s) ... + bool stoppedTransmit = false; + + if (_pluginReceive != null) + { + foreach (IRServerPluginBase plugin in _pluginReceive) + { + try + { + IRemoteReceiver remoteReceiver = plugin as IRemoteReceiver; + if (remoteReceiver != null) + remoteReceiver.RemoteCallback -= new RemoteHandler(RemoteHandlerCallback); + + IKeyboardReceiver keyboardReceiver = plugin as IKeyboardReceiver; + if (keyboardReceiver != null) + keyboardReceiver.KeyboardCallback -= new KeyboardHandler(KeyboardHandlerCallback); + + IMouseReceiver mouseReceiver = plugin as IMouseReceiver; + if (mouseReceiver != null) + mouseReceiver.MouseCallback -= new MouseHandler(MouseHandlerCallback); + + plugin.Stop(); + + if (plugin == _pluginTransmit) + { + stoppedTransmit = true; + IrssLog.Info("Transmit and Receive plugin stopped: \"{0}\"", plugin.Name); + } + else + { + IrssLog.Info("Receiver plugin stopped: \"{0}\"", plugin.Name); + } + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + } + } + + _pluginReceive = null; + } + + try + { + if (_pluginTransmit != null && !stoppedTransmit) + _pluginTransmit.Stop(); + + _pluginTransmit = null; + } + 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 ..."); + + bool suspendedTransmit = false; + + if (_pluginReceive != null) + { + foreach (IRServerPluginBase plugin in _pluginReceive) + { + if (plugin == _pluginTransmit) + suspendedTransmit = true; + + plugin.Suspend(); + } + } + + if (_pluginTransmit != null && !suspendedTransmit) + _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 ..."); + + bool resumedTransmit = false; + + if (_pluginReceive != null) + { + foreach (IRServerPluginBase plugin in _pluginReceive) + { + if (plugin == _pluginTransmit) + resumedTransmit = true; + + plugin.Resume(); + } + } + + if (_pluginTransmit != null && !resumedTransmit) + _pluginTransmit.Resume(); + + // TODO: Inform clients ? + break; + } + + return true; + } + + #region Unused + + protected override void OnPause() + { + base.OnPause(); + } + + protected override void OnContinue() + { + base.OnContinue(); + } + + protected override void OnSessionChange(SessionChangeDescription changeDescription) + { + switch (changeDescription.Reason) + { + case SessionChangeReason.SessionLogon: + break; + + case SessionChangeReason.SessionLogoff: + break; + } + + base.OnSessionChange(changeDescription); + } + + protected override void OnCustomCommand(int command) + { + switch (command) + { + case 128: + break; + } + + base.OnCustomCommand(command); + } + + #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(Server.DefaultPort, sink); + _server.ClientDisconnectCallback = new WaitCallback(ClientDisconnect); + + _server.Start(); + } + void StopServer() + { + if (_server != null) + { + _server.Dispose(); + _server = null; + } + + if (_registeredClients != null) + { + _registeredClients.Clear(); + _registeredClients = null; + } + + if (_registeredRepeaters != 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); + } + + void ClientDisconnect(object obj) + { + ClientManager clientManager = obj as ClientManager; + + if (clientManager != null) + { + UnregisterClient(clientManager); + UnregisterRepeater(clientManager); + } + } + + bool StartClient(IPEndPoint endPoint) + { + if (_client != null) + return false; + + ClientMessageSink sink = new ClientMessageSink(ClientReceivedMessage); + + _client = new Client(endPoint, 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) + { + _client.Dispose(); + _client = null; + } + } + + bool StartRelay() + { + try + { + StartServer(); + + IPAddress serverIP = Client.GetIPFromName(_hostComputer); + IPEndPoint endPoint = new IPEndPoint(serverIP, IrssComms.Server.DefaultPort); + + StartClient(endPoint); + + return true; + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + return false; + } + } + void StopRelay() + { + try + { + StopServer(); + StopClient(); + } + catch { } + } + + bool StartRepeater() + { + try + { + StartServer(); + + IPAddress serverIP = Client.GetIPFromName(_hostComputer); + IPEndPoint endPoint = new IPEndPoint(serverIP, IrssComms.Server.DefaultPort); + + StartClient(endPoint); + + 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); + } + } + catch + { + throw; + } + finally + { + StopServer(); + StopClient(); + } + } + + 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) + { + + #region ForwardRemoteEvent + case MessageType.ForwardRemoteEvent: + if (_mode == IRServerMode.RelayMode) + { + IrssMessage forward = new IrssMessage(MessageType.ForwardRemoteEvent, MessageFlags.Request, combo.Message.GetDataAsBytes()); + _client.Send(forward); + } + else + { + IrssMessage forward = new IrssMessage(MessageType.RemoteEvent, MessageFlags.Notify, combo.Message.GetDataAsBytes()); + SendToAllExcept(combo.Manager, forward); + } + break; + #endregion ForwardRemoteEvent + + #region ForwardKeyboardEvent + case MessageType.ForwardKeyboardEvent: + if (_mode == IRServerMode.RelayMode) + { + IrssMessage forward = new IrssMessage(MessageType.ForwardKeyboardEvent, MessageFlags.Request, combo.Message.GetDataAsBytes()); + _client.Send(forward); + } + else + { + IrssMessage forward = new IrssMessage(MessageType.KeyboardEvent, MessageFlags.Notify, combo.Message.GetDataAsBytes()); + SendToAllExcept(combo.Manager, forward); + } + break; + #endregion ForwardKeyboardEvent + + #region ForwardMouseEvent + case MessageType.ForwardMouseEvent: + if (_mode == IRServerMode.RelayMode) + { + IrssMessage forward = new IrssMessage(MessageType.ForwardMouseEvent, MessageFlags.Request, combo.Message.GetDataAsBytes()); + _client.Send(forward); + } + else + { + IrssMessage forward = new IrssMessage(MessageType.MouseEvent, MessageFlags.Notify, combo.Message.GetDataAsBytes()); + SendToAllExcept(combo.Manager, forward); + } + break; + #endregion ForwardMouseEvent + + #region BlastIR + 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.GetDataAsBytes())) + response.Flags |= MessageFlags.Success; + else + response.Flags |= MessageFlags.Failure; + } + + if ((combo.Message.Flags & MessageFlags.ForceNotRespond) != MessageFlags.ForceNotRespond) + SendTo(combo.Manager, response); + + break; + } + #endregion BlastIR + + #region LearnIR + 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.SetDataAsBytes(bytes); + break; + + case LearnStatus.Failure: + response.Flags |= MessageFlags.Failure; + break; + + case LearnStatus.Timeout: + response.Flags |= MessageFlags.Timeout; + break; + } + } + + SendTo(combo.Manager, response); + break; + } + #endregion LearnIR + + #region ServerShutdown + case MessageType.ServerShutdown: + if ((combo.Message.Flags & MessageFlags.Request) == MessageFlags.Request) + { + IrssLog.Info("Shutdown command received"); + Stop(); + } + break; + #endregion ServerShutdown + + #region RegisterClient + 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.SetDataAsBytes(irServerInfo.ToBytes()); + response.Flags |= MessageFlags.Success; + } + else + { + response.Flags |= MessageFlags.Failure; + } + + SendTo(combo.Manager, response); + break; + } + #endregion RegisterClient + + #region UnregisterClient + case MessageType.UnregisterClient: + UnregisterClient(combo.Manager); + break; + #endregion UnregisterClient + + #region RegisterRepeater + 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; + } + #endregion RegisterRepeater + + #region UnregisterRepeater + case MessageType.UnregisterRepeater: + UnregisterRepeater(combo.Manager); + break; + #endregion UnregisterRepeater + + #region ActiveBlasters + case MessageType.ActiveBlasters: + { + IrssMessage response = new IrssMessage(MessageType.ActiveBlasters, MessageFlags.Response); + response.SetDataAsString(_pluginNameTransmit); + + SendTo(combo.Manager, response); + break; + } + #endregion ActiveBlasters + + #region ActiveReceivers + case MessageType.ActiveReceivers: + { + IrssMessage response = new IrssMessage(MessageType.ActiveReceivers, MessageFlags.Response); + + if (_pluginNameReceive != null) + { + StringBuilder receivers = new StringBuilder(); + for (int index = 0; index < _pluginNameReceive.Length; index++) + { + receivers.Append(_pluginNameReceive[index]); + + if (index < _pluginNameReceive.Length - 1) + receivers.Append(','); + } + + response.SetDataAsString(receivers.ToString()); + } + else + { + response.SetDataAsString(null); + } + + SendTo(combo.Manager, response); + break; + } + #endregion ActiveReceivers + + #region AvailableBlasters + case MessageType.AvailableBlasters: + { + IrssMessage response = new IrssMessage(MessageType.AvailableBlasters, MessageFlags.Response); + + IRServerPluginBase[] plugins = Program.AvailablePlugins(); + StringBuilder blasters = new StringBuilder(); + + for (int index = 0; index < plugins.Length; index++) + { + IRServerPluginBase plugin = plugins[index]; + + if (plugin is ITransmitIR) + { + blasters.Append(plugin.Name); + blasters.Append(','); + } + } + + if (blasters.Length == 0) + { + response.SetDataAsString(null); + } + else + { + blasters.Remove(blasters.Length - 1, 1); + response.SetDataAsString(blasters.ToString()); + } + + SendTo(combo.Manager, response); + break; + } + #endregion AvailableBlasters + + #region AvailableReceivers + case MessageType.AvailableReceivers: + { + IrssMessage response = new IrssMessage(MessageType.AvailableReceivers, MessageFlags.Response); + + IRServerPluginBase[] plugins = Program.AvailablePlugins(); + StringBuilder receivers = new StringBuilder(); + + for (int index = 0; index < plugins.Length; index++) + { + IRServerPluginBase plugin = plugins[index]; + + if (plugin is IRemoteReceiver || plugin is IKeyboardReceiver || plugin is IMouseReceiver) + { + receivers.Append(plugin.Name); + receivers.Append(','); + } + } + + if (receivers.Length == 0) + { + response.SetDataAsString(null); + } + else + { + receivers.Remove(receivers.Length - 1, 1); + response.SetDataAsString(receivers.ToString()); + } + + SendTo(combo.Manager, response); + break; + } + #endregion AvailableReceivers + + #region DetectedBlasters + case MessageType.DetectedBlasters: + { + IrssMessage response = new IrssMessage(MessageType.DetectedBlasters, MessageFlags.Response); + string[] detectedBlasters = Program.DetectBlasters(); + + if (detectedBlasters != null) + { + StringBuilder blasters = new StringBuilder(); + for (int index = 0; index < detectedBlasters.Length; index++) + { + blasters.Append(detectedBlasters[index]); + + if (index < detectedBlasters.Length - 1) + blasters.Append(','); + } + + response.SetDataAsString(blasters.ToString()); + } + else + { + response.SetDataAsString(null); + } + + SendTo(combo.Manager, response); + break; + } + #endregion DetectedBlasters + + #region DetectedReceivers + case MessageType.DetectedReceivers: + { + IrssMessage response = new IrssMessage(MessageType.DetectedReceivers, MessageFlags.Response); + string[] detectedReceivers = Program.DetectReceivers(); + + if (detectedReceivers != null) + { + StringBuilder receivers = new StringBuilder(); + for (int index = 0; index < detectedReceivers.Length; index++) + { + receivers.Append(detectedReceivers[index]); + + if (index < detectedReceivers.Length - 1) + receivers.Append(','); + } + + response.SetDataAsString(receivers.ToString()); + } + else + { + response.SetDataAsString(null); + } + + SendTo(combo.Manager, response); + break; + } + #endregion DetectedReceivers + + } + } + 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() + { + _mode = IRServerMode.ServerMode; + _hostComputer = String.Empty; + _pluginNameReceive = null; + _pluginNameTransmit = String.Empty; + + XmlDocument doc = new XmlDocument(); + + try + { + doc.Load(ConfigurationFile); + } + catch (FileNotFoundException) + { + IrssLog.Warn("No configuration file found ({0}), creating default configuration file", ConfigurationFile); + + string[] blasters = Program.DetectBlasters(); + if (blasters == null) + _pluginNameTransmit = String.Empty; + else + _pluginNameTransmit = blasters[0]; + + string[] receivers = Program.DetectReceivers(); + if (receivers == null) + _pluginNameReceive = null; + else + _pluginNameReceive = receivers; + + SaveSettings(); + return; + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + return; + } + + try { _mode = (IRServerMode)Enum.Parse(typeof(IRServerMode), doc.DocumentElement.Attributes["Mode"].Value, true); } + catch (Exception ex) { IrssLog.Warn(ex.ToString()); } + + try { _hostComputer = doc.DocumentElement.Attributes["HostComputer"].Value; } + catch (Exception ex) { IrssLog.Warn(ex.ToString()); } + + try { _pluginNameTransmit = doc.DocumentElement.Attributes["PluginTransmit"].Value; } + catch (Exception ex) { IrssLog.Warn(ex.ToString()); } + + try + { + string receivers = doc.DocumentElement.Attributes["PluginReceive"].Value; + if (!String.IsNullOrEmpty(receivers)) + _pluginNameReceive = receivers.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + } + catch (Exception ex) + { + IrssLog.Warn(ex.ToString()); + } + } + void SaveSettings() + { + try + { + using (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("PluginTransmit", _pluginNameTransmit); + + if (_pluginNameReceive != null) + { + StringBuilder receivers = new StringBuilder(); + for (int index = 0; index < _pluginNameReceive.Length; index++) + { + receivers.Append(_pluginNameReceive[index]); + + if (index < _pluginNameReceive.Length - 1) + receivers.Append(','); + } + writer.WriteAttributeString("PluginReceive", receivers.ToString()); + } + else + { + writer.WriteAttributeString("PluginReceive", String.Empty); + } + + writer.WriteEndElement(); // </settings> + writer.WriteEndDocument(); + } + } + catch (Exception ex) + { + IrssLog.Error(ex.ToString()); + } + } + + } + +} Added: trunk/plugins/IR Server Suite/Input Service/Input Service/InputServiceInstaller.cs =================================================================== --- trunk/plugins/IR Server Suite/Input Service/Input Service/InputServiceInstaller.cs (rev 0) +++ trunk/plugins/IR Server Suite/Input Service/Input Service/InputServiceInstaller.cs 2007-10-05 15:41:56 UTC (rev 977) @@ -0,0 +1,91 @@ +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 + { + throw; + } + finally + { + if (InParam != null) + InParam.Dispose(); + + if (OutParam != null) + OutParam.Dispose(); + } + } + */ + } + +} Added: trunk/plugins/IR Server Suite/Input Service/Input Service/Program.cs =================================================================== --- trunk/plugins/IR Server Suite/Input Service/Input Service/Program.cs (rev 0) +++ trunk/plugins/IR Server Suite/Input Service/Input Service/Program.cs 2007-10-05 15:41:56 UTC (rev 977) @@ -0,0 +1,203 @@ +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 IRServerPluginInterface; +using IrssUtils; + +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 IRServerPluginBase[] AvailablePlugins() + { + try + { + List<IRServerPluginBase> plugins = new List<IRServerPluginBase>(); + + 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(IRServerPluginBase))) + { + IRServerPluginBase plugin = (IRServerPluginBase)assembly.CreateInstance(type.FullName); + + if (plugin != null) + plugins.Add(plugin); + } + } + } + catch (BadImageFormatException) + { + // Ignore Bad Image Format Exceptions, just keep checking for IR Server Plugins + } + catch (TypeLoadException) + { + // Ignore Type Load Exceptions, just keep checking for IR Server Plugins + } + } + + return plugins.ToArray(); + } +#if TRACE + catch (Exception ex) + { + Trace.WriteLine("IRServer: " + ex.ToString()); +#else + catch + { +#endif + 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 IRServerPluginBase GetPlugin(string pluginName) + { + if (String.IsNullOrEmpty(pluginName)) + throw new ArgumentNullException("pluginName"); + + IRServerPluginBase[] serverPlugins = AvailablePlugins(); + if (serverPlugins == null) + throw new FileNotFoundException("No available plugins found"); + + foreach (IRServerPluginBase plugin in serverPlugins) + if (plugin.Name.Equals(pluginName, StringComparison.InvariantCultureIgnoreCase)) + return plugin; + + return null; + } + + /// <summary> + /// Retreives a list of detected Receiver plugins. + /// </summary> + /// <returns>String array of plugin names.</returns> + internal static string[] DetectReceivers() + { + try + { + IRServerPluginBase[] plugins = AvailablePlugins(); + + List<string> receivers = new List<string>(); + + foreach (IRServerPluginBase plugin in plugins) + if ((plugin is IRemoteReceiver || plugin is IKeyboardReceiver || plugin is IMouseReceiver) && plugin.Detect()) + receivers.Add(plugin.Name); + + if (receivers.Count > 0) + return receivers.ToArray(); + } +#if TRACE + catch (Exception ex) + { + Trace.WriteLine("IRServer: " + ex.ToString()); + } +#else + catch + { + } +#endif + + return null; + } + + /// <summary> + /// Retreives a list of detected Blaster plugins. + /// </summary> + /// <returns>String array of plugin names.</returns> + internal static string[] DetectBlasters() + { + try + { + IRServerPluginBase[] plugins = Program.AvailablePlugins(); + + List<string> blasters = new List<string>(); + + foreach (IRServerPluginBase plugin in plugins) + if (plugin is ITransmitIR && plugin.Detect()) + blasters.Add(plugin.Name); + + if (blasters.Count > 0) + return blasters.ToArray(); + } +#if TRACE + catch (Exception ex) + { + Tra... [truncated message content] |