// --------------------------------------------------------------------------------------------------------------------
//
// 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
}
}