// -------------------------------------------------------------------------------------------------------------------- // // This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. // // // Background Service Connector. // HandBrake has the ability to connect to a service app that will control HandBrakeCLI or Libhb. // This acts as process isolation. // // -------------------------------------------------------------------------------------------------------------------- namespace HandBrake.ApplicationServices.Isolation { using System; using System.Diagnostics; using System.ServiceModel; using System.Threading; using HandBrake.ApplicationServices.EventArgs; using HandBrake.ApplicationServices.Exceptions; using HandBrake.ApplicationServices.Services.Interfaces; /// /// Background Service Connector. /// HandBrake has the ability to connect to a service app that will control HandBrakeCLI or Libhb. /// This acts as process isolation. /// public class BackgroundServiceConnector : IHbServiceCallback, IDisposable { #region Constants and Fields /// /// Gets or sets the pipe factory. /// DuplexChannelFactory is necessary for Callbacks. /// private static DuplexChannelFactory pipeFactory; /// /// The background process. /// private static Process backgroundProcess; #endregion #region Properties /// /// Gets or sets a value indicating whether is connected. /// public bool IsConnected { get; set; } /// /// Gets or sets the service. /// public IServerService Service { get; set; } #endregion #region Public Server Management Methods /// /// The can connect. /// /// /// The System.Boolean. /// public bool CanConnect() { return true; } /// /// The connect. /// /// /// The port. /// public void Connect(string port) { if (backgroundProcess == null) { ProcessStartInfo processStartInfo = new ProcessStartInfo( "HandBrake.Server.exe", port) { UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, }; backgroundProcess = new Process { StartInfo = processStartInfo }; backgroundProcess.Start(); } // When the process writes out a line, it's pipe server is ready and can be contacted for // work. Reading line blocks until this happens. backgroundProcess.StandardOutput.ReadLine(); ThreadPool.QueueUserWorkItem(delegate { try { pipeFactory = new DuplexChannelFactory( new InstanceContext(this), new NetTcpBinding(), new EndpointAddress(string.Format("net.tcp://127.0.0.1:{0}/IHbService", port))); // Connect and Subscribe to the Server this.Service = pipeFactory.CreateChannel(); this.Service.Subscribe(); this.IsConnected = true; } catch (Exception exc) { throw new GeneralApplicationException("Unable to connect to background worker process", "Please restart HandBrake", exc); } }); } /// /// The disconnect. /// public void Shutdown() { try { if (backgroundProcess != null && !backgroundProcess.HasExited) { this.Service.Unsubscribe(); } } catch (Exception exc) { throw new GeneralApplicationException("Unable to disconnect to background worker process", "It may have already close. Check for any left over HandBrake.Server.exe processes", exc); } } #endregion #region Implemented Interfaces /// /// The dispose. /// public void Dispose() { this.Service.Unsubscribe(); } /// /// The encode progress callback. /// /// /// The event Args. /// public virtual void EncodeProgressCallback(EncodeProgressEventArgs eventArgs) { } /// /// The encode completed callback. /// /// /// The event Args. /// public virtual void EncodeCompletedCallback(EncodeCompletedEventArgs eventArgs) { } /// /// The encode started callback. /// public virtual void EncodeStartedCallback() { } #endregion } }