From 83af0dca6f4ecc16d5a4dcc6b6ccd97b707f7156 Mon Sep 17 00:00:00 2001 From: sr55 Date: Tue, 25 Sep 2012 15:23:17 +0000 Subject: WinGui: LibHb Encode and Scan support (off by default for the moment until I have time to test this and tidy up some of the code) Can be turned on in preferences. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4980 b64f7644-9d1e-0410-96f1-a4d463321fa5 --- .../HandBrake.ApplicationServices.csproj | 14 +- .../Isolation/BackgroundServiceConnector.cs | 214 +++++++++++++++ .../Isolation/IsolatedEncodeService.cs | 185 +++++++++++++ .../Isolation/IsolatedScanService.cs | 216 +++++++++++++++ .../Services/Encode.cs | 8 + .../Services/Interfaces/IEncode.cs | 5 + .../Services/Interfaces/IEncodeServiceWrapper.cs | 18 ++ .../Services/Interfaces/IQueueProcessor.cs | 4 +- .../Services/Interfaces/IScan.cs | 5 + .../Services/Interfaces/IScanServiceWrapper.cs | 18 ++ .../Services/LibEncode.cs | 21 +- .../Services/LibScan.cs | 20 +- .../Services/QueueProcessor.cs | 8 +- .../Services/ScanService.cs | 11 +- .../ServicesWindsorInstaller.cs | 4 +- win/CS/HandBrake10.sln | 8 +- win/CS/HandBrakeWPF/HandBrakeWPF.csproj | 10 +- .../Isolation/BackgroundServiceConnector.cs | 289 --------------------- .../Isolation/Interfaces/IIsolatedEncodeService.cs | 24 -- .../Isolation/Interfaces/IIsolatedScanService.cs | 24 -- .../Isolation/IsolatedEncodeService.cs | 192 -------------- .../HandBrakeWPF/Isolation/IsolatedScanService.cs | 223 ---------------- .../HandBrakeWPF/Services/EncodeServiceWrapper.cs | 257 ++++++++++++++++++ win/CS/HandBrakeWPF/Services/ScanServiceWrapper.cs | 243 +++++++++++++++++ win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs | 5 + win/CS/HandBrakeWPF/UserSettingConstants.cs | 5 + win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs | 54 +--- win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs | 23 ++ win/CS/HandBrakeWPF/Views/Images/warningsmall.png | Bin 0 -> 618 bytes win/CS/HandBrakeWPF/Views/OptionsView.xaml | 3 +- win/CS/HandBrakeWPF/defaultsettings.xml | 8 + 31 files changed, 1290 insertions(+), 829 deletions(-) create mode 100644 win/CS/HandBrake.ApplicationServices/Isolation/BackgroundServiceConnector.cs create mode 100644 win/CS/HandBrake.ApplicationServices/Isolation/IsolatedEncodeService.cs create mode 100644 win/CS/HandBrake.ApplicationServices/Isolation/IsolatedScanService.cs create mode 100644 win/CS/HandBrake.ApplicationServices/Services/Interfaces/IEncodeServiceWrapper.cs create mode 100644 win/CS/HandBrake.ApplicationServices/Services/Interfaces/IScanServiceWrapper.cs delete mode 100644 win/CS/HandBrakeWPF/Isolation/BackgroundServiceConnector.cs delete mode 100644 win/CS/HandBrakeWPF/Isolation/Interfaces/IIsolatedEncodeService.cs delete mode 100644 win/CS/HandBrakeWPF/Isolation/Interfaces/IIsolatedScanService.cs delete mode 100644 win/CS/HandBrakeWPF/Isolation/IsolatedEncodeService.cs delete mode 100644 win/CS/HandBrakeWPF/Isolation/IsolatedScanService.cs create mode 100644 win/CS/HandBrakeWPF/Services/EncodeServiceWrapper.cs create mode 100644 win/CS/HandBrakeWPF/Services/ScanServiceWrapper.cs create mode 100644 win/CS/HandBrakeWPF/Views/Images/warningsmall.png (limited to 'win') diff --git a/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj b/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj index 463ccc4ca..402448984 100644 --- a/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj +++ b/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj @@ -20,12 +20,12 @@ x86 - bin\x86\Debug\ + bin\Debug\ DEBUG;TRACE x86 - bin\x86\Release\ + bin\Release\ true DEBUG;TRACE pdbonly @@ -33,12 +33,12 @@ x64 - bin\x64\Debug\ + bin\Debug\ TRACE;DEBUG x64 - bin\x64\Release\ + bin\Release\ DEBUG;TRACE true pdbonly @@ -105,7 +105,12 @@ + + + + + @@ -185,7 +190,6 @@ {F0A61F62-2C3B-4A87-AFF4-0C4256253DA1} HandBrakeInterop - False diff --git a/win/CS/HandBrake.ApplicationServices/Isolation/BackgroundServiceConnector.cs b/win/CS/HandBrake.ApplicationServices/Isolation/BackgroundServiceConnector.cs new file mode 100644 index 000000000..4044e8a61 --- /dev/null +++ b/win/CS/HandBrake.ApplicationServices/Isolation/BackgroundServiceConnector.cs @@ -0,0 +1,214 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// 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 + + #region IDisposable + + /// + /// The dispose. + /// + public void Dispose() + { + this.Service.Unsubscribe(); + } + + #endregion + + #region IHbServiceCallback + + /// + /// The scan completed. + /// + /// + /// The event args. + /// + public virtual void ScanCompletedCallback(ScanCompletedEventArgs eventArgs) + { + } + + /// + /// The scan progress. + /// + /// + /// The event args. + /// + public virtual void ScanProgressCallback(ScanProgressEventArgs eventArgs) + { + } + + /// + /// The scan started callback. + /// + public virtual void ScanStartedCallback() + { + } + + /// + /// 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 + + #endregion + } +} \ No newline at end of file diff --git a/win/CS/HandBrake.ApplicationServices/Isolation/IsolatedEncodeService.cs b/win/CS/HandBrake.ApplicationServices/Isolation/IsolatedEncodeService.cs new file mode 100644 index 000000000..6806e2844 --- /dev/null +++ b/win/CS/HandBrake.ApplicationServices/Isolation/IsolatedEncodeService.cs @@ -0,0 +1,185 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Isolated Scan Service +// This is an implementation of the IEncode implementation that runs scans on a seperate process +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrake.ApplicationServices.Isolation +{ + using System; + using System.Threading; + + using HandBrake.ApplicationServices.EventArgs; + using HandBrake.ApplicationServices.Exceptions; + using HandBrake.ApplicationServices.Model; + using HandBrake.ApplicationServices.Services.Interfaces; + + /// + /// Isolated Scan Service. + /// This is an implementation of the IEncode implementation that runs scans on a seperate process + /// + public class IsolatedEncodeService : BackgroundServiceConnector, IEncode + { + #region Constructors and Destructors + + /// + /// Initializes a new instance of the class. + /// + /// + /// The port. + /// + public IsolatedEncodeService(string port) + { + try + { + if (this.CanConnect()) + { + this.Connect(port); + } + } + catch (Exception exception) + { + throw new GeneralApplicationException("Unable to connect to scan worker process.", "Try restarting HandBrake", exception); + } + } + + #endregion + + #region Events + + /// + /// The encode completed. + /// + public event EncodeCompletedStatus EncodeCompleted; + + /// + /// The encode started. + /// + public event EventHandler EncodeStarted; + + /// + /// The encode status changed. + /// + public event EncodeProgessStatus EncodeStatusChanged; + + #endregion + + #region Properties + + /// + /// Gets ActivityLog. + /// + public string ActivityLog + { + get + { + return this.IsConnected ? this.Service.EncodeActivityLog : "Unable to connect to background worker service ..."; + } + } + + /// + /// Gets a value indicating whether IsEncoding. + /// + public bool IsEncoding + { + get + { + return this.IsConnected && this.Service.IsEncoding; + } + } + + #endregion + + #region Public Methods + + /// + /// The encode completed callback. + /// + /// + /// The event args. + /// + public override void EncodeCompletedCallback(EncodeCompletedEventArgs eventArgs) + { + if (this.EncodeCompleted != null) + { + ThreadPool.QueueUserWorkItem(delegate { this.EncodeCompleted(this, eventArgs); }); + } + + base.EncodeCompletedCallback(eventArgs); + } + + /// + /// The encode progress callback. + /// + /// + /// The event args. + /// + public override void EncodeProgressCallback(EncodeProgressEventArgs eventArgs) + { + if (this.EncodeStatusChanged != null) + { + ThreadPool.QueueUserWorkItem(delegate { this.EncodeStatusChanged(this, eventArgs); }); + } + + base.EncodeProgressCallback(eventArgs); + } + + #endregion + + #region Implemented Interfaces + + #region IEncode + + /// + /// Copy the log file to the desired destinations + /// + /// + /// The destination. + /// + public void ProcessLogs(string destination) + { + ThreadPool.QueueUserWorkItem(delegate { this.Service.ProcessEncodeLogs(destination); }); + } + + /// + /// Attempt to Safely kill a DirectRun() CLI + /// NOTE: This will not work with a MinGW CLI + /// Note: http://www.cygwin.com/ml/cygwin/2006-03/msg00330.html + /// + public void SafelyStop() + { + ThreadPool.QueueUserWorkItem(delegate { this.Service.StopEncode(); }); + } + + /// + /// Start with a LibHb EncodeJob Object + /// + /// + /// The job. + /// + /// + /// The enable Logging. + /// + public void Start(QueueTask job, bool enableLogging) + { + ThreadPool.QueueUserWorkItem( + delegate { this.Service.StartEncode(job, enableLogging); }); + } + + /// + /// Kill the CLI process + /// + public void Stop() + { + ThreadPool.QueueUserWorkItem(delegate { this.Service.StopEncode(); }); + } + + #endregion + + #endregion + } +} \ No newline at end of file diff --git a/win/CS/HandBrake.ApplicationServices/Isolation/IsolatedScanService.cs b/win/CS/HandBrake.ApplicationServices/Isolation/IsolatedScanService.cs new file mode 100644 index 000000000..dcef0cc44 --- /dev/null +++ b/win/CS/HandBrake.ApplicationServices/Isolation/IsolatedScanService.cs @@ -0,0 +1,216 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// Isolated Scan Service +// This is an implementation of the IScan implementation that runs scans on a seperate process +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrake.ApplicationServices.Isolation +{ + using System; + using System.Threading; + + using HandBrake.ApplicationServices.EventArgs; + using HandBrake.ApplicationServices.Exceptions; + using HandBrake.ApplicationServices.Parsing; + using HandBrake.ApplicationServices.Services.Interfaces; + + /// + /// Isolated Scan Service. + /// This is an implementation of the IScan implementation that runs scans on a seperate process + /// + public class IsolatedScanService : BackgroundServiceConnector, IScan + { + #region Constants and Fields + + /// + /// The post action. + /// + private Action postScanAction; + + #endregion + + #region Events + + /// + /// The scan completed. + /// + public event ScanCompletedStatus ScanCompleted; + + /// + /// The scan stared. + /// + public event EventHandler ScanStared; + + /// + /// The scan status changed. + /// + public event ScanProgessStatus ScanStatusChanged; + + #endregion + + /// + /// Initializes a new instance of the class. + /// + /// + /// The port. + /// + public IsolatedScanService(string port) + { + try + { + if (this.CanConnect()) + { + this.Connect(port); + } + } + catch (Exception exception) + { + throw new GeneralApplicationException("Unable to connect to scan worker process.", "Try restarting HandBrake", exception); + } + } + + #region Properties + + /// + /// Gets ActivityLog. + /// + public string ActivityLog + { + get + { + return this.Service.ScanActivityLog; + } + } + + /// + /// Gets a value indicating whether IsScanning. + /// + public bool IsScanning + { + get + { + return this.Service.IsScanning; + } + } + + /// + /// Gets the Souce Data. + /// + public Source SouceData + { + get + { + return this.Service.SouceData; + } + } + + #endregion + + #region Public Methods + + /// + /// The scan completed callback. + /// + /// + /// The event args. + /// + public override void ScanCompletedCallback(ScanCompletedEventArgs eventArgs) + { + if (this.postScanAction != null) + { + this.postScanAction(true); + } + + if (this.ScanCompleted != null) + { + ThreadPool.QueueUserWorkItem(delegate { this.ScanCompleted(this, eventArgs); }); + } + + base.ScanCompletedCallback(eventArgs); + } + + /// + /// The scan progress callback. + /// + /// + /// The event args. + /// + public override void ScanProgressCallback(ScanProgressEventArgs eventArgs) + { + if (this.ScanStatusChanged != null) + { + ThreadPool.QueueUserWorkItem(delegate { this.ScanStatusChanged(this, eventArgs); }); + } + + base.ScanProgressCallback(eventArgs); + } + + /// + /// The scan started callback. + /// + public override void ScanStartedCallback() + { + if (this.ScanStared != null) + { + ThreadPool.QueueUserWorkItem(delegate { this.ScanStared(this, EventArgs.Empty); }); + } + + base.ScanStartedCallback(); + } + + #endregion + + #region Implemented Interfaces + + #region IScan + + /// + /// Take a Scan Log file, and process it as if it were from the CLI. + /// + /// + /// The path to the log file. + /// + public void DebugScanLog(string path) + { + throw new NotImplementedException("Not available in process isolation mode!"); + } + + /// + /// Scan a Source Path. + /// Title 0: scan all + /// + /// + /// Path to the file to scan + /// + /// + /// int title number. 0 for scan all + /// + /// + /// The preview Count. + /// + /// + /// The post Action. + /// + public void Scan(string sourcePath, int title, int previewCount, Action postAction) + { + this.postScanAction = postAction; + this.Service.ScanSource(sourcePath, title, previewCount); + } + + /// + /// Kill the scan + /// + public void Stop() + { + this.Service.StopScan(); + } + + #endregion + + #endregion + } +} \ No newline at end of file diff --git a/win/CS/HandBrake.ApplicationServices/Services/Encode.cs b/win/CS/HandBrake.ApplicationServices/Services/Encode.cs index fa21353ed..49ff66bd2 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/Encode.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/Encode.cs @@ -264,6 +264,14 @@ namespace HandBrake.ApplicationServices.Services //}*/ } + /// + /// Shutdown the service. + /// + public void Shutdown() + { + // Nothing to do. + } + #endregion #region Private Helper Methods diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IEncode.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IEncode.cs index 426cad897..eddc49d9b 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IEncode.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IEncode.cs @@ -96,5 +96,10 @@ namespace HandBrake.ApplicationServices.Services.Interfaces /// The destination. /// void ProcessLogs(string destination); + + /// + /// Shutdown the service. + /// + void Shutdown(); } } \ No newline at end of file diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IEncodeServiceWrapper.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IEncodeServiceWrapper.cs new file mode 100644 index 000000000..95f20e455 --- /dev/null +++ b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IEncodeServiceWrapper.cs @@ -0,0 +1,18 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// IEncodeServiceWrapper Interface +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrake.ApplicationServices.Services.Interfaces +{ + /// + /// EncodeServiceWrapper Interface + /// + public interface IEncodeServiceWrapper : IEncode + { + } +} diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs index b695bab49..dd5746387 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IQueueProcessor.cs @@ -34,7 +34,7 @@ namespace HandBrake.ApplicationServices.Services.Interfaces /// /// Gets the IEncodeService instance. /// - IEncode EncodeService { get; } + IEncodeServiceWrapper EncodeService { get; } /// /// Gets the IQueueManager instance. @@ -64,6 +64,6 @@ namespace HandBrake.ApplicationServices.Services.Interfaces /// /// The service. /// - void SwapEncodeService(IEncode service); + void SwapEncodeService(IEncodeServiceWrapper service); } } \ No newline at end of file diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IScan.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IScan.cs index cd69084eb..59213e5d0 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IScan.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IScan.cs @@ -101,5 +101,10 @@ namespace HandBrake.ApplicationServices.Services.Interfaces /// The path to the log file. /// void DebugScanLog(string path); + + /// + /// Shutdown the service. + /// + void Shutdown(); } } \ No newline at end of file diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IScanServiceWrapper.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IScanServiceWrapper.cs new file mode 100644 index 000000000..febe4aa29 --- /dev/null +++ b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IScanServiceWrapper.cs @@ -0,0 +1,18 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// ScanServiceWrapper Interface +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrake.ApplicationServices.Services.Interfaces +{ + /// + /// ScanServiceWrapper Interface + /// + public interface IScanServiceWrapper : IScan + { + } +} diff --git a/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs b/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs index 404a47fac..5c3deb80f 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/LibEncode.cs @@ -12,6 +12,7 @@ namespace HandBrake.ApplicationServices.Services using System; using System.Diagnostics; + using HandBrake.ApplicationServices.Exceptions; using HandBrake.ApplicationServices.Model; using HandBrake.ApplicationServices.Services.Base; using HandBrake.ApplicationServices.Services.Interfaces; @@ -163,7 +164,7 @@ namespace HandBrake.ApplicationServices.Services } catch (Exception exc) { - this.Invoke_encodeCompleted(new EncodeCompletedEventArgs(false, exc, "An Error has occured in EncodeService.Run()")); + this.Invoke_encodeCompleted(new EncodeCompletedEventArgs(false, exc, "An Error has occured.")); } } @@ -184,7 +185,15 @@ namespace HandBrake.ApplicationServices.Services /// public override void Stop(Exception exc) { - this.instance.StopEncode(); + try + { + this.IsEncoding = false; + this.instance.StopEncode(); + } + catch(Exception) + { + // Do Nothing. + } this.Invoke_encodeCompleted( exc == null @@ -202,6 +211,14 @@ namespace HandBrake.ApplicationServices.Services throw new NotImplementedException("This Method is not used in the LibEncode service. You should use the Stop() method instead! "); } + /// + /// Shutdown the service. + /// + public void Shutdown() + { + // Nothing to do for this implementation. + } + #region HandBrakeInstance Event Handlers. /// /// Log a message diff --git a/win/CS/HandBrake.ApplicationServices/Services/LibScan.cs b/win/CS/HandBrake.ApplicationServices/Services/LibScan.cs index 73f5fca57..c3598d922 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/LibScan.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/LibScan.cs @@ -183,6 +183,14 @@ namespace HandBrake.ApplicationServices.Services throw new NotImplementedException("Only Available when using the CLI mode. Not LibHB"); } + /// + /// Shutdown the service. + /// + public void Shutdown() + { + // Nothing to do for this implementation. + } + #endregion #region Private Methods @@ -205,7 +213,8 @@ namespace HandBrake.ApplicationServices.Services { this.logging.Clear(); - string source = sourcePath.ToString().EndsWith("\\") ? sourcePath.ToString() : "\"" + sourcePath + "\""; + string source = sourcePath.ToString().EndsWith("\\") ? string.Format("\"{0}\\\\\"", sourcePath.ToString().TrimEnd('\\')) + : "\"" + sourcePath + "\""; currentSourceScanPath = source; IsScanning = true; @@ -240,7 +249,14 @@ namespace HandBrake.ApplicationServices.Services /// private void InstanceScanCompleted(object sender, EventArgs e) { - this.SouceData = new Source { Titles = ConvertTitles(this.instance.Titles), ScanPath = currentSourceScanPath}; + // TODO -> Might be a better place to fix this. + string path = currentSourceScanPath; + if (currentSourceScanPath.Contains("\"")) + { + path = currentSourceScanPath.Trim('\"'); + } + + this.SouceData = new Source { Titles = ConvertTitles(this.instance.Titles), ScanPath = path }; IsScanning = false; diff --git a/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs b/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs index bbb085916..29eba5172 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/QueueProcessor.cs @@ -43,7 +43,7 @@ namespace HandBrake.ApplicationServices.Services /// /// Services are not setup /// - public QueueProcessor(IQueueManager queueManager, IEncode encodeService, IUserSettingService userSettingService) + public QueueProcessor(IQueueManager queueManager, IEncodeServiceWrapper encodeService, IUserSettingService userSettingService) { this.userSettingService = userSettingService; this.QueueManager = queueManager; @@ -147,7 +147,7 @@ namespace HandBrake.ApplicationServices.Services /// /// Gets the IEncodeService instance. /// - public IEncode EncodeService { get; private set; } + public IEncodeServiceWrapper EncodeService { get; private set; } /// /// Gets the IQueueManager instance. @@ -188,7 +188,7 @@ namespace HandBrake.ApplicationServices.Services /// /// The service. /// - public void SwapEncodeService(IEncode service) + public void SwapEncodeService(IEncodeServiceWrapper service) { this.EncodeService = service; } @@ -260,8 +260,8 @@ namespace HandBrake.ApplicationServices.Services QueueTask job = this.QueueManager.GetNextJobForProcessing(); if (job != null) { - this.EncodeService.Start(job, true); this.InvokeJobProcessingStarted(new QueueProgressEventArgs(job)); + this.EncodeService.Start(job, true); } else { diff --git a/win/CS/HandBrake.ApplicationServices/Services/ScanService.cs b/win/CS/HandBrake.ApplicationServices/Services/ScanService.cs index 9eb05eb39..e2ce19ff0 100644 --- a/win/CS/HandBrake.ApplicationServices/Services/ScanService.cs +++ b/win/CS/HandBrake.ApplicationServices/Services/ScanService.cs @@ -16,8 +16,6 @@ namespace HandBrake.ApplicationServices.Services using System.Threading; using System.Windows.Forms; - using Caliburn.Micro; - using HandBrake.ApplicationServices.EventArgs; using HandBrake.ApplicationServices.Exceptions; using HandBrake.ApplicationServices.Parsing; @@ -194,6 +192,15 @@ namespace HandBrake.ApplicationServices.Services throw new GeneralApplicationException("Debug Run Failed", string.Empty, e); } } + + /// + /// Shutdown the service. + /// + public void Shutdown() + { + // Nothing to do for this implementation. + } + #endregion #region Private Methods diff --git a/win/CS/HandBrake.ApplicationServices/ServicesWindsorInstaller.cs b/win/CS/HandBrake.ApplicationServices/ServicesWindsorInstaller.cs index 6d5b40ef6..d2e0f0bb7 100644 --- a/win/CS/HandBrake.ApplicationServices/ServicesWindsorInstaller.cs +++ b/win/CS/HandBrake.ApplicationServices/ServicesWindsorInstaller.cs @@ -33,8 +33,8 @@ namespace HandBrake.ApplicationServices container.Register(Component.For().ImplementedBy()); container.Register(Component.For().ImplementedBy()); container.Register(Component.For().ImplementedBy()); - container.Register(Component.For().ImplementedBy()); - container.Register(Component.For().ImplementedBy()); + // container.Register(Component.For().ImplementedBy()); + // container.Register(Component.For().ImplementedBy()); } #endregion diff --git a/win/CS/HandBrake10.sln b/win/CS/HandBrake10.sln index 97de9a5d0..4878465ae 100644 --- a/win/CS/HandBrake10.sln +++ b/win/CS/HandBrake10.sln @@ -44,12 +44,14 @@ Global {DADE66CB-0E12-4959-ADE5-0ACD31D27C59}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {DADE66CB-0E12-4959-ADE5-0ACD31D27C59}.Debug|Mixed Platforms.Build.0 = Debug|x86 {DADE66CB-0E12-4959-ADE5-0ACD31D27C59}.Debug|x64.ActiveCfg = Debug|x64 + {DADE66CB-0E12-4959-ADE5-0ACD31D27C59}.Debug|x64.Build.0 = Debug|x64 {DADE66CB-0E12-4959-ADE5-0ACD31D27C59}.Debug|x86.ActiveCfg = Debug|x86 {DADE66CB-0E12-4959-ADE5-0ACD31D27C59}.Debug|x86.Build.0 = Debug|x86 {DADE66CB-0E12-4959-ADE5-0ACD31D27C59}.Release|Any CPU.ActiveCfg = Release|x86 {DADE66CB-0E12-4959-ADE5-0ACD31D27C59}.Release|Mixed Platforms.ActiveCfg = Release|x86 {DADE66CB-0E12-4959-ADE5-0ACD31D27C59}.Release|Mixed Platforms.Build.0 = Release|x86 {DADE66CB-0E12-4959-ADE5-0ACD31D27C59}.Release|x64.ActiveCfg = Release|x64 + {DADE66CB-0E12-4959-ADE5-0ACD31D27C59}.Release|x64.Build.0 = Release|x64 {DADE66CB-0E12-4959-ADE5-0ACD31D27C59}.Release|x86.ActiveCfg = Release|x86 {DADE66CB-0E12-4959-ADE5-0ACD31D27C59}.Release|x86.Build.0 = Release|x86 {F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}.Debug|Any CPU.ActiveCfg = Debug|x86 @@ -69,13 +71,15 @@ Global {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Debug|Any CPU.ActiveCfg = Debug|x86 {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Debug|x64.ActiveCfg = Debug|x86 + {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Debug|x64.ActiveCfg = Debug|x64 + {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Debug|x64.Build.0 = Debug|x64 {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Debug|x86.ActiveCfg = Debug|x86 {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Debug|x86.Build.0 = Debug|x86 {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Release|Any CPU.ActiveCfg = Release|x86 {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Release|Mixed Platforms.ActiveCfg = Release|x86 {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Release|Mixed Platforms.Build.0 = Release|x86 - {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Release|x64.ActiveCfg = Release|x86 + {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Release|x64.ActiveCfg = Release|x64 + {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Release|x64.Build.0 = Release|x64 {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Release|x86.ActiveCfg = Release|x86 {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Release|x86.Build.0 = Release|x86 EndGlobalSection diff --git a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj index dcaf10f3d..bae0eff7a 100644 --- a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj +++ b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj @@ -55,7 +55,7 @@ true - bin\x64\Debug\ + bin\Debug\ DEBUG;TRACE full x64 @@ -128,18 +128,15 @@ - - - - - + + ShellView.xaml @@ -368,6 +365,7 @@ Always + diff --git a/win/CS/HandBrakeWPF/Isolation/BackgroundServiceConnector.cs b/win/CS/HandBrakeWPF/Isolation/BackgroundServiceConnector.cs deleted file mode 100644 index 13bf132ee..000000000 --- a/win/CS/HandBrakeWPF/Isolation/BackgroundServiceConnector.cs +++ /dev/null @@ -1,289 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// 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 HandBrakeWPF.Isolation -{ - using System; - using System.Diagnostics; - using System.ServiceModel; - using System.Threading; - - using HandBrake.ApplicationServices.EventArgs; - using HandBrake.ApplicationServices.Services.Interfaces; - - using HandBrakeWPF.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 - - /// - /// The error service. - /// - private readonly IErrorService errorService; - - /// - /// The user setting service. - /// - private readonly IUserSettingService userSettingService; - - /// - /// 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 - - /// - /// Initializes a new instance of the class. - /// - /// - /// The error service. - /// - /// - /// The user Setting Service. - /// - public BackgroundServiceConnector(IErrorService errorService, IUserSettingService userSettingService) - { - this.errorService = errorService; - this.userSettingService = userSettingService; - } - - /// - /// 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. - /// - public void Connect() - { - string port = this.userSettingService.GetUserSetting(UserSettingConstants.ServerPort); - - 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 - Service = pipeFactory.CreateChannel(); - Service.Subscribe(); - IsConnected = true; - } - catch (Exception exc) - { - Caliburn.Micro.Execute.OnUIThread(() => this.errorService.ShowError("Unable to connect to background worker service", "Please restart HandBrake", exc)); - } - }); - } - - /// - /// The disconnect. - /// - public void Disconnect() - { - try - { - if (backgroundProcess != null && !backgroundProcess.HasExited) - { - Service.Unsubscribe(); - } - } - catch (Exception exc) - { - this.errorService.ShowError("Unable to disconnect from service", "It may have already close. Check for any left over HandBrake.Server.exe processes", exc); - } - } - - #endregion - - #region Public Service Methods - - ///// - ///// The scan source. - ///// - ///// - ///// The path. - ///// - ///// - ///// The title. - ///// - ///// - ///// The preview count. - ///// - //public void ScanSource(string path, int title, int previewCount) - //{ - // ThreadPool.QueueUserWorkItem(delegate { this.Service.ScanSource(path, title, previewCount); }); - //} - - ///// - ///// The stop scan. - ///// - //public void StopScan() - //{ - // ThreadPool.QueueUserWorkItem(delegate { this.Service.StopScan(); }); - //} - - ///// - ///// Start an Encode - ///// - ///// - ///// The job. - ///// - ///// - ///// The enable logging. - ///// - //public void StartEncode(QueueTask job, bool enableLogging) - //{ - // ThreadPool.QueueUserWorkItem(delegate { this.Service.StartEncode(job, enableLogging); }); - //} - - ///// - ///// Stop an Encode - ///// - //public void StopEncode() - //{ - // ThreadPool.QueueUserWorkItem(delegate { this.Service.StopEncode(); }); - //} - - #endregion - - #region Implemented Interfaces - - #region IDisposable - - /// - /// The dispose. - /// - public void Dispose() - { - Service.Unsubscribe(); - } - - #endregion - - #region IHbServiceCallback - - /// - /// The scan completed. - /// - /// - /// The event args. - /// - public virtual void ScanCompletedCallback(ScanCompletedEventArgs eventArgs) - { - } - - /// - /// The scan progress. - /// - /// - /// The event args. - /// - public virtual void ScanProgressCallback(ScanProgressEventArgs eventArgs) - { - } - - /// - /// The scan started callback. - /// - public virtual void ScanStartedCallback() - { - } - - /// - /// 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 - - #endregion - } -} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Isolation/Interfaces/IIsolatedEncodeService.cs b/win/CS/HandBrakeWPF/Isolation/Interfaces/IIsolatedEncodeService.cs deleted file mode 100644 index fb9912ccf..000000000 --- a/win/CS/HandBrakeWPF/Isolation/Interfaces/IIsolatedEncodeService.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. -// -// -// The Isolated Encode Service interface. -// -// -------------------------------------------------------------------------------------------------------------------- - -namespace HandBrakeWPF.Isolation.Interfaces -{ - using HandBrake.ApplicationServices.Services.Interfaces; - - /// - /// The Isolated Encode Service interface. - /// - public interface IIsolatedEncodeService : IEncode - { - /// - /// The disconnect. - /// - void Disconnect(); - } -} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Isolation/Interfaces/IIsolatedScanService.cs b/win/CS/HandBrakeWPF/Isolation/Interfaces/IIsolatedScanService.cs deleted file mode 100644 index 7b94deb58..000000000 --- a/win/CS/HandBrakeWPF/Isolation/Interfaces/IIsolatedScanService.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. -// -// -// The Isolated Scan Service interface. -// -// -------------------------------------------------------------------------------------------------------------------- - -namespace HandBrakeWPF.Isolation.Interfaces -{ - using HandBrake.ApplicationServices.Services.Interfaces; - - /// - /// The Isolated Scan Service interface. - /// - public interface IIsolatedScanService : IScan - { - /// - /// The disconnect. - /// - void Disconnect(); - } -} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Isolation/IsolatedEncodeService.cs b/win/CS/HandBrakeWPF/Isolation/IsolatedEncodeService.cs deleted file mode 100644 index 322d30f9f..000000000 --- a/win/CS/HandBrakeWPF/Isolation/IsolatedEncodeService.cs +++ /dev/null @@ -1,192 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. -// -// -// Isolated Scan Service -// This is an implementation of the IEncode implementation that runs scans on a seperate process -// -// -------------------------------------------------------------------------------------------------------------------- - -namespace HandBrakeWPF.Isolation -{ - using System; - using System.Threading; - - using HandBrake.ApplicationServices.EventArgs; - using HandBrake.ApplicationServices.Model; - using HandBrake.ApplicationServices.Services.Interfaces; - - using HandBrakeWPF.Isolation.Interfaces; - using HandBrakeWPF.Services.Interfaces; - - /// - /// Isolated Scan Service. - /// This is an implementation of the IEncode implementation that runs scans on a seperate process - /// - public class IsolatedEncodeService : BackgroundServiceConnector, IIsolatedEncodeService - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// The error Service. - /// - /// - /// The user Setting Service. - /// - public IsolatedEncodeService(IErrorService errorService, IUserSettingService userSettingService) - : base(errorService, userSettingService) - { - try - { - if (this.CanConnect()) - { - this.Connect(); - } - } - catch (Exception exception) - { - errorService.ShowError( - "Unable to connect to scan worker process.", "Try restarting HandBrake", exception); - } - } - - #endregion - - #region Events - - /// - /// The encode completed. - /// - public event EncodeCompletedStatus EncodeCompleted; - - /// - /// The encode started. - /// - public event EventHandler EncodeStarted; - - /// - /// The encode status changed. - /// - public event EncodeProgessStatus EncodeStatusChanged; - - #endregion - - #region Properties - - /// - /// Gets ActivityLog. - /// - public string ActivityLog - { - get - { - return this.IsConnected ? this.Service.EncodeActivityLog : "Unable to connect to background worker service ..."; - } - } - - /// - /// Gets a value indicating whether IsEncoding. - /// - public bool IsEncoding - { - get - { - return this.IsConnected && this.Service.IsEncoding; - } - } - - #endregion - - #region Public Methods - - /// - /// The encode completed callback. - /// - /// - /// The event args. - /// - public override void EncodeCompletedCallback(EncodeCompletedEventArgs eventArgs) - { - if (this.EncodeCompleted != null) - { - ThreadPool.QueueUserWorkItem(delegate { this.EncodeCompleted(this, eventArgs); }); - } - - base.EncodeCompletedCallback(eventArgs); - } - - /// - /// The encode progress callback. - /// - /// - /// The event args. - /// - public override void EncodeProgressCallback(EncodeProgressEventArgs eventArgs) - { - if (this.EncodeStatusChanged != null) - { - ThreadPool.QueueUserWorkItem(delegate { this.EncodeStatusChanged(this, eventArgs); }); - } - - base.EncodeProgressCallback(eventArgs); - } - - #endregion - - #region Implemented Interfaces - - #region IEncode - - /// - /// Copy the log file to the desired destinations - /// - /// - /// The destination. - /// - public void ProcessLogs(string destination) - { - ThreadPool.QueueUserWorkItem(delegate { Service.ProcessEncodeLogs(destination); }); - } - - /// - /// Attempt to Safely kill a DirectRun() CLI - /// NOTE: This will not work with a MinGW CLI - /// Note: http://www.cygwin.com/ml/cygwin/2006-03/msg00330.html - /// - public void SafelyStop() - { - ThreadPool.QueueUserWorkItem(delegate { Service.StopEncode(); }); - } - - /// - /// Start with a LibHb EncodeJob Object - /// - /// - /// The job. - /// - /// - /// The enable Logging. - /// - public void Start(QueueTask job, bool enableLogging) - { - ThreadPool.QueueUserWorkItem( - delegate { Service.StartEncode(job, enableLogging); }); - } - - /// - /// Kill the CLI process - /// - public void Stop() - { - ThreadPool.QueueUserWorkItem(delegate { Service.StopEncode(); }); - } - - #endregion - - #endregion - } -} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Isolation/IsolatedScanService.cs b/win/CS/HandBrakeWPF/Isolation/IsolatedScanService.cs deleted file mode 100644 index b50f1b3ea..000000000 --- a/win/CS/HandBrakeWPF/Isolation/IsolatedScanService.cs +++ /dev/null @@ -1,223 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. -// -// -// Isolated Scan Service -// This is an implementation of the IScan implementation that runs scans on a seperate process -// -// -------------------------------------------------------------------------------------------------------------------- - -namespace HandBrakeWPF.Isolation -{ - using System; - using System.Threading; - - using HandBrake.ApplicationServices.EventArgs; - using HandBrake.ApplicationServices.Parsing; - using HandBrake.ApplicationServices.Services.Interfaces; - - using HandBrakeWPF.Isolation.Interfaces; - using HandBrakeWPF.Services.Interfaces; - - /// - /// Isolated Scan Service. - /// This is an implementation of the IScan implementation that runs scans on a seperate process - /// - public class IsolatedScanService : BackgroundServiceConnector, IIsolatedScanService - { - #region Constants and Fields - - /// - /// The post action. - /// - private Action postScanAction; - - #endregion - - #region Events - - /// - /// The scan completed. - /// - public event ScanCompletedStatus ScanCompleted; - - /// - /// The scan stared. - /// - public event EventHandler ScanStared; - - /// - /// The scan status changed. - /// - public event ScanProgessStatus ScanStatusChanged; - - #endregion - - /// - /// Initializes a new instance of the class. - /// - /// - /// The error Service. - /// - /// - /// The user Setting Service. - /// - public IsolatedScanService(IErrorService errorService, IUserSettingService userSettingService) - : base(errorService, userSettingService) - { - try - { - if (this.CanConnect()) - { - this.Connect(); - } - } - catch (Exception exception) - { - errorService.ShowError( - "Unable to connect to scan worker process.", "Try restarting HandBrake", exception); - } - } - - #region Properties - - /// - /// Gets ActivityLog. - /// - public string ActivityLog - { - get - { - return Service.ScanActivityLog; - } - } - - /// - /// Gets a value indicating whether IsScanning. - /// - public bool IsScanning - { - get - { - return Service.IsScanning; - } - } - - /// - /// Gets the Souce Data. - /// - public Source SouceData - { - get - { - return Service.SouceData; - } - } - - #endregion - - #region Public Methods - - /// - /// The scan completed callback. - /// - /// - /// The event args. - /// - public override void ScanCompletedCallback(ScanCompletedEventArgs eventArgs) - { - if (this.postScanAction != null) - { - this.postScanAction(true); - } - - if (this.ScanCompleted != null) - { - ThreadPool.QueueUserWorkItem(delegate { this.ScanCompleted(this, eventArgs); }); - } - - base.ScanCompletedCallback(eventArgs); - } - - /// - /// The scan progress callback. - /// - /// - /// The event args. - /// - public override void ScanProgressCallback(ScanProgressEventArgs eventArgs) - { - if (this.ScanStatusChanged != null) - { - ThreadPool.QueueUserWorkItem(delegate { this.ScanStatusChanged(this, eventArgs); }); - } - - base.ScanProgressCallback(eventArgs); - } - - /// - /// The scan started callback. - /// - public override void ScanStartedCallback() - { - if (this.ScanStared != null) - { - ThreadPool.QueueUserWorkItem(delegate { this.ScanStared(this, EventArgs.Empty); }); - } - - base.ScanStartedCallback(); - } - - #endregion - - #region Implemented Interfaces - - #region IScan - - /// - /// Take a Scan Log file, and process it as if it were from the CLI. - /// - /// - /// The path to the log file. - /// - public void DebugScanLog(string path) - { - throw new NotImplementedException("Not available in process isolation mode!"); - } - - /// - /// Scan a Source Path. - /// Title 0: scan all - /// - /// - /// Path to the file to scan - /// - /// - /// int title number. 0 for scan all - /// - /// - /// The preview Count. - /// - /// - /// The post Action. - /// - public void Scan(string sourcePath, int title, int previewCount, Action postAction) - { - this.postScanAction = postAction; - Service.ScanSource(sourcePath, title, previewCount); - } - - /// - /// Kill the scan - /// - public void Stop() - { - Service.StopScan(); - } - - #endregion - - #endregion - } -} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/EncodeServiceWrapper.cs b/win/CS/HandBrakeWPF/Services/EncodeServiceWrapper.cs new file mode 100644 index 000000000..79d79164f --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/EncodeServiceWrapper.cs @@ -0,0 +1,257 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// We have multiple implementations of IEncode. This is a wrapper class for the GUI so that the +// implementation used is controllable via user settings. +// Over time, this class will go away when the LibHB and process isolation code matures. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services +{ + using System; + + using Caliburn.Micro; + + using HandBrake.ApplicationServices.Exceptions; + using HandBrake.ApplicationServices.Isolation; + using HandBrake.ApplicationServices.Model; + using HandBrake.ApplicationServices.Services; + using HandBrake.ApplicationServices.Services.Interfaces; + using HandBrake.Interop.Interfaces; + + using EncodeCompletedEventArgs = HandBrake.ApplicationServices.EventArgs.EncodeCompletedEventArgs; + using EncodeProgressEventArgs = HandBrake.ApplicationServices.EventArgs.EncodeProgressEventArgs; + + /// + /// We have multiple implementations of Iencode. This is a wrapper class for the GUI so that the + /// implementation used is controllable via user settings. + /// Over time, this class will go away when the LibHB and process isolation code matures. + /// + public class EncodeServiceWrapper : IEncodeServiceWrapper + { + #region Constants and Fields + + /// + /// The encode service. + /// + private readonly IEncode encodeService; + + #endregion + + #region Constructors and Destructors + + /// + /// Initializes a new instance of the class. + /// + /// + /// The user setting service. + /// + public EncodeServiceWrapper(IUserSettingService userSettingService) + { + var useLibHb = userSettingService.GetUserSetting(UserSettingConstants.EnableLibHb); + var useProcessIsolation = + userSettingService.GetUserSetting(UserSettingConstants.EnableProcessIsolation); + var port = userSettingService.GetUserSetting(UserSettingConstants.ServerPort); + + if (useLibHb) + { + try + { + if (useProcessIsolation) + { + this.encodeService = new IsolatedEncodeService(port); + } + else + { + IHandBrakeInstance handBrakeInstance = IoC.Get(); + this.encodeService = new LibEncode(userSettingService, handBrakeInstance); + } + } + catch (Exception exc) + { + // Try to recover from errors. + userSettingService.SetUserSetting(UserSettingConstants.EnableLibHb, false); + throw new GeneralApplicationException( + "Unable to initialise LibHB or Background worker service", + "Falling back to using HandBrakeCLI.exe. Setting has been reset", + exc); + } + } + else + { + this.encodeService = new Encode(userSettingService); + } + + this.encodeService.EncodeCompleted += this.EncodeServiceEncodeCompleted; + this.encodeService.EncodeStarted += this.EncodeServiceEncodeStarted; + this.encodeService.EncodeStatusChanged += this.EncodeServiceEncodeStatusChanged; + } + + #endregion + + #region Events + + /// + /// The encode completed. + /// + public event EncodeCompletedStatus EncodeCompleted; + + /// + /// The encode started. + /// + public event EventHandler EncodeStarted; + + /// + /// The encode status changed. + /// + public event EncodeProgessStatus EncodeStatusChanged; + + #endregion + + #region Properties + + /// + /// Gets ActivityLog. + /// + public string ActivityLog + { + get + { + return this.encodeService.ActivityLog; + } + } + + /// + /// Gets a value indicating whether IsEncoding. + /// + public bool IsEncoding + { + get + { + return this.encodeService.IsEncoding; + } + } + + #endregion + + #region Implemented Interfaces + + #region IEncode + + /// + /// Copy the log file to the desired destinations + /// + /// + /// The destination. + /// + public void ProcessLogs(string destination) + { + this.encodeService.ProcessLogs(destination); + } + + /// + /// Attempt to Safely kill a DirectRun() CLI + /// NOTE: This will not work with a MinGW CLI + /// Note: http://www.cygwin.com/ml/cygwin/2006-03/msg00330.html + /// + public void SafelyStop() + { + this.encodeService.SafelyStop(); + } + + /// + /// Shutdown the service. + /// + public void Shutdown() + { + this.encodeService.Shutdown(); + this.encodeService.EncodeCompleted -= this.EncodeServiceEncodeCompleted; + this.encodeService.EncodeStarted -= this.EncodeServiceEncodeStarted; + this.encodeService.EncodeStatusChanged -= this.EncodeServiceEncodeStatusChanged; + } + + /// + /// Start with a LibHb EncodeJob Object + /// + /// + /// The job. + /// + /// + /// The enable Logging. + /// + public void Start(QueueTask job, bool enableLogging) + { + this.encodeService.Start(job, enableLogging); + } + + /// + /// Kill the CLI process + /// + public void Stop() + { + this.encodeService.Stop(); + } + + #endregion + + #endregion + + #region Methods + + /// + /// The encode service_ encode completed. + /// + /// + /// The sender. + /// + /// + /// The EncodeCompletedEventArgs. + /// + private void EncodeServiceEncodeCompleted(object sender, EncodeCompletedEventArgs e) + { + if (EncodeCompleted != null) + { + this.EncodeCompleted(sender, e); + } + } + + /// + /// The encode service_ encode started. + /// + /// + /// The sender. + /// + /// + /// The EventArgs + /// + private void EncodeServiceEncodeStarted(object sender, EventArgs e) + { + if (EncodeStarted != null) + { + this.EncodeStarted(sender, e); + } + } + + /// + /// The encode service_ encode status changed. + /// + /// + /// The sender. + /// + /// + /// The EncodeProgressEventArgs. + /// + private void EncodeServiceEncodeStatusChanged(object sender, EncodeProgressEventArgs e) + { + if (EncodeStatusChanged != null) + { + this.EncodeStatusChanged(sender, e); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Services/ScanServiceWrapper.cs b/win/CS/HandBrakeWPF/Services/ScanServiceWrapper.cs new file mode 100644 index 000000000..a25213a6b --- /dev/null +++ b/win/CS/HandBrakeWPF/Services/ScanServiceWrapper.cs @@ -0,0 +1,243 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. +// +// +// We have multiple implementations of IScan. This is a wrapper class for the GUI so that the +// implementation used is controllable via user settings. +// Over time, this class will go away when the LibHB and process isolation code matures. +// +// -------------------------------------------------------------------------------------------------------------------- + +namespace HandBrakeWPF.Services +{ + using System; + + using Caliburn.Micro; + + using HandBrake.ApplicationServices.Exceptions; + using HandBrake.ApplicationServices.Isolation; + using HandBrake.ApplicationServices.Parsing; + using HandBrake.ApplicationServices.Services; + using HandBrake.ApplicationServices.Services.Interfaces; + using HandBrake.Interop.Interfaces; + + /// + /// We have multiple implementations of IScan. This is a wrapper class for the GUI so that the + /// implementation used is controllable via user settings. + /// Over time, this class will go away when the LibHB and process isolation code matures. + /// + public class ScanServiceWrapper : IScanServiceWrapper + { + #region Constants and Fields + + /// + /// The scan service. + /// + private readonly IScan scanService; + + #endregion + + #region Constructors and Destructors + + /// + /// Initializes a new instance of the class. + /// + /// + /// The user setting service. + /// + public ScanServiceWrapper(IUserSettingService userSettingService) + { + var useLibHb = userSettingService.GetUserSetting(UserSettingConstants.EnableLibHb); + var useProcessIsolation = + userSettingService.GetUserSetting(UserSettingConstants.EnableProcessIsolation); + string port = userSettingService.GetUserSetting(UserSettingConstants.ServerPort); + + if (useLibHb) + { + try + { + if (useProcessIsolation) + { + this.scanService = new IsolatedScanService(port); + } + else + { + IHandBrakeInstance handBrakeInstance = IoC.Get(); + this.scanService = new LibScan(userSettingService, handBrakeInstance); + } + } + catch(Exception exc) + { + // Try to recover from errors. + userSettingService.SetUserSetting(UserSettingConstants.EnableLibHb, false); + throw new GeneralApplicationException("Unable to initialise LibHB or Background worker service", "Falling back to using HandBrakeCLI.exe. Setting has been reset", exc); + } + } + else + { + this.scanService = new ScanService(userSettingService); + } + + this.scanService.ScanCompleted += this.ScanServiceScanCompleted; + this.scanService.ScanStared += this.ScanServiceScanStared; + this.scanService.ScanStatusChanged += this.ScanServiceScanStatusChanged; + } + + /// + /// The scan service scan status changed event + /// + /// + /// The sender. + /// + /// + /// The ScanProgressEventArgs. + /// + private void ScanServiceScanStatusChanged(object sender, HandBrake.ApplicationServices.EventArgs.ScanProgressEventArgs e) + { + this.ScanStatusChanged(sender, e); + } + + /// + /// The scan service scan stared event + /// + /// + /// The sender. + /// + /// + /// The EventArgs + /// + private void ScanServiceScanStared(object sender, EventArgs e) + { + this.ScanStared(sender, e); + } + + /// + /// The scan service scan completed event + /// + /// + /// The sender. + /// + /// + /// The ScanCompletedEventArgs + /// + private void ScanServiceScanCompleted(object sender, HandBrake.ApplicationServices.EventArgs.ScanCompletedEventArgs e) + { + this.ScanCompleted(sender, e); + } + + #endregion + + #region Events + + /// + /// The scan completed. + /// + public event ScanCompletedStatus ScanCompleted; + + /// + /// The scan stared. + /// + public event EventHandler ScanStared; + + /// + /// The scan status changed. + /// + public event ScanProgessStatus ScanStatusChanged; + + #endregion + + #region Properties + + /// + /// Gets ActivityLog. + /// + public string ActivityLog + { + get + { + return this.scanService.ActivityLog; + } + } + + /// + /// Gets a value indicating whether IsScanning. + /// + public bool IsScanning + { + get + { + return this.scanService.IsScanning; + } + } + + /// + /// Gets the Souce Data. + /// + public Source SouceData + { + get + { + return this.scanService.SouceData; + } + } + + #endregion + + #region Implemented Interfaces + + #region IScan + + /// + /// Take a Scan Log file, and process it as if it were from the CLI. + /// + /// + /// The path to the log file. + /// + public void DebugScanLog(string path) + { + this.scanService.DebugScanLog(path); + } + + /// + /// Shutdown the service. + /// + public void Shutdown() + { + this.scanService.Shutdown(); + } + + /// + /// Scan a Source Path. + /// Title 0: scan all + /// + /// + /// Path to the file to scan + /// + /// + /// int title number. 0 for scan all + /// + /// + /// The preview Count. + /// + /// + /// The post Action. + /// + public void Scan(string sourcePath, int title, int previewCount, Action postAction) + { + this.scanService.Scan(sourcePath, title, previewCount, postAction); + } + + /// + /// Kill the scan + /// + public void Stop() + { + this.scanService.Stop(); + } + + #endregion + + #endregion + } +} \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs b/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs index dadae2026..e34f98ada 100644 --- a/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs +++ b/win/CS/HandBrakeWPF/Startup/CastleBootstrapper.cs @@ -21,6 +21,8 @@ namespace HandBrakeWPF.Startup using Castle.Windsor; using HandBrake.ApplicationServices; + using HandBrake.ApplicationServices.Services.Interfaces; + using HandBrake.Interop; using ViewModels; using ViewModels.Interfaces; @@ -49,11 +51,14 @@ namespace HandBrakeWPF.Startup // Initialise the ApplicationServices IWindsorInstaller this.windsorContainer.Register(Component.For().ImplementedBy()); + this.windsorContainer.Register(Component.For().ImplementedBy()); this.windsorContainer.Install(windsorContainer.ResolveAll()); // Services this.windsorContainer.Register(Component.For().ImplementedBy().LifeStyle.Is(LifestyleType.Singleton)); this.windsorContainer.Register(Component.For().ImplementedBy().LifeStyle.Is(LifestyleType.Singleton)); + this.windsorContainer.Register(Component.For().ImplementedBy().LifeStyle.Is(LifestyleType.Singleton)); + this.windsorContainer.Register(Component.For().ImplementedBy().LifeStyle.Is(LifestyleType.Singleton)); // Shell this.windsorContainer.Register(Component.For().ImplementedBy().LifeStyle.Is(LifestyleType.Singleton)); diff --git a/win/CS/HandBrakeWPF/UserSettingConstants.cs b/win/CS/HandBrakeWPF/UserSettingConstants.cs index 77cd9ab8f..440b65bf5 100644 --- a/win/CS/HandBrakeWPF/UserSettingConstants.cs +++ b/win/CS/HandBrakeWPF/UserSettingConstants.cs @@ -176,6 +176,11 @@ namespace HandBrakeWPF /// public const string EnableDebugFeatures = "EnableDebugFeatures"; + /// + /// Enable the use of LibHb instead of HandBrakeCLI + /// + public const string EnableLibHb = "EnableLibHb"; + #endregion } } \ No newline at end of file diff --git a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs index 86c8d3a14..a0e9d62c2 100644 --- a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs @@ -29,8 +29,6 @@ namespace HandBrakeWPF.ViewModels using HandBrakeWPF.Commands; using HandBrakeWPF.Helpers; - using HandBrakeWPF.Isolation; - using HandBrakeWPF.Isolation.Interfaces; using HandBrakeWPF.Model; using HandBrakeWPF.Services.Interfaces; using HandBrakeWPF.ViewModels.Interfaces; @@ -85,12 +83,12 @@ namespace HandBrakeWPF.ViewModels /// /// The Source Scan Service. /// - private IScan scanService; + private readonly IScanServiceWrapper scanService; /// /// The Encode Service /// - private IEncode encodeService; + private readonly IEncodeServiceWrapper encodeService; /// /// HandBrakes Main Window Title @@ -191,7 +189,7 @@ namespace HandBrakeWPF.ViewModels /// /// The drive Detect Service. /// - public MainViewModel(IUserSettingService userSettingService, IScan scanService, IEncode encodeService, IPresetService presetService, + public MainViewModel(IUserSettingService userSettingService, IScanServiceWrapper scanService, IEncodeServiceWrapper encodeService, IPresetService presetService, IErrorService errorService, IShellViewModel shellViewModel, IUpdateService updateService, IDriveDetectService driveDetectService) { GeneralUtilities.SetInstanceId(); @@ -817,11 +815,6 @@ namespace HandBrakeWPF.ViewModels this.SourceMenu = this.GenerateSourceMenu(); this.driveDetectService.StartDetection(this.DriveTrayChanged); - - if (this.userSettingService.GetUserSetting(UserSettingConstants.EnableProcessIsolation)) - { - this.EnableIsolationServices(); - } } /// @@ -832,19 +825,8 @@ namespace HandBrakeWPF.ViewModels // Shutdown Service this.driveDetectService.Close(); - IIsolatedScanService isolatedScanService = this.scanService as IsolatedScanService; - if (isolatedScanService != null) - { - // Kill any background services for this instance of HandBrake. - isolatedScanService.Disconnect(); - } - - IIsolatedEncodeService isolatedEncodeService = this.encodeService as IIsolatedEncodeService; - if (isolatedEncodeService != null) - { - // Kill any background services for this instance of HandBrake. - isolatedEncodeService.Disconnect(); - } + this.scanService.Shutdown(); + this.encodeService.Shutdown(); // Unsubscribe from Events. this.scanService.ScanStared -= this.ScanStared; @@ -977,7 +959,6 @@ namespace HandBrakeWPF.ViewModels this.errorService.ShowMessageBox("There are jobs on the queue with the same destination path. Please choose a different path for this job.", "Error", MessageBoxButton.OK, MessageBoxImage.Warning); } - if (!this.IsEncoding) { this.ProgramStatusLabel = string.Format("{0} Encodes Pending", this.queueProcessor.QueueManager.Count); @@ -1111,7 +1092,6 @@ namespace HandBrakeWPF.ViewModels return; } - if (File.Exists(this.Destination)) { MessageBoxResult result = this.errorService.ShowMessageBox("The current file already exists, do you wish to overwrite it?", "Question", MessageBoxButton.YesNo, MessageBoxImage.Question); @@ -1200,30 +1180,6 @@ namespace HandBrakeWPF.ViewModels } } - /// - /// The test isolation services. - /// Swaps out the implementation of IScan to the IsolatedScanService version. - /// - public void EnableIsolationServices() - { - // Unhook the old services - this.scanService.ScanStared -= this.ScanStared; - this.scanService.ScanCompleted -= this.ScanCompleted; - this.scanService.ScanStatusChanged -= this.ScanStatusChanged; - this.queueProcessor.EncodeService.EncodeStatusChanged -= this.EncodeStatusChanged; - - // Replace the Services - this.scanService = new IsolatedScanService(this.errorService, this.userSettingService); - this.encodeService = new IsolatedEncodeService(this.errorService, this.userSettingService); - this.queueProcessor.SwapEncodeService(this.encodeService); - - // Add the new Event Hooks - this.scanService.ScanStared += this.ScanStared; - this.scanService.ScanCompleted += this.ScanCompleted; - this.scanService.ScanStatusChanged += this.ScanStatusChanged; - this.queueProcessor.EncodeService.EncodeStatusChanged += this.EncodeStatusChanged; - } - #endregion #region Main Window Public Methods diff --git a/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs index 7b65a5ef8..1bd773bc0 100644 --- a/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs +++ b/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs @@ -354,6 +354,11 @@ namespace HandBrakeWPF.ViewModels /// private bool enableDebugFeatures; + /// + /// Backing field for EnableLibHb + /// + private bool enableLibHb; + #endregion #region Constructors and Destructors @@ -1374,6 +1379,22 @@ namespace HandBrakeWPF.ViewModels } } + /// + /// Gets or sets a value indicating whether enable lib hb. + /// + public bool EnableLibHb + { + get + { + return this.enableLibHb; + } + set + { + this.enableLibHb = value; + this.NotifyOfPropertyChange(() => this.EnableLibHb); + } + } + #endregion #endregion @@ -1670,6 +1691,7 @@ namespace HandBrakeWPF.ViewModels this.ServerPort = port; this.EnableProcessIsolation = userSettingService.GetUserSetting(UserSettingConstants.EnableProcessIsolation); this.EnableDebugFeatures = userSettingService.GetUserSetting(UserSettingConstants.EnableDebugFeatures); + this.EnableLibHb = userSettingService.GetUserSetting(UserSettingConstants.EnableLibHb); } /// @@ -1887,6 +1909,7 @@ namespace HandBrakeWPF.ViewModels userSettingService.SetUserSetting(UserSettingConstants.EnableProcessIsolation, this.EnableProcessIsolation); userSettingService.SetUserSetting(UserSettingConstants.ServerPort, this.ServerPort.ToString()); userSettingService.SetUserSetting(UserSettingConstants.EnableDebugFeatures, this.EnableDebugFeatures); + userSettingService.SetUserSetting(UserSettingConstants.EnableLibHb, this.EnableLibHb); } /// diff --git a/win/CS/HandBrakeWPF/Views/Images/warningsmall.png b/win/CS/HandBrakeWPF/Views/Images/warningsmall.png new file mode 100644 index 000000000..78f246f04 Binary files /dev/null and b/win/CS/HandBrakeWPF/Views/Images/warningsmall.png differ diff --git a/win/CS/HandBrakeWPF/Views/OptionsView.xaml b/win/CS/HandBrakeWPF/Views/OptionsView.xaml index d0135db47..4412c7bfb 100644 --- a/win/CS/HandBrakeWPF/Views/OptionsView.xaml +++ b/win/CS/HandBrakeWPF/Views/OptionsView.xaml @@ -337,7 +337,8 @@ - + + diff --git a/win/CS/HandBrakeWPF/defaultsettings.xml b/win/CS/HandBrakeWPF/defaultsettings.xml index 0c995c9e9..80a1e6e2c 100644 --- a/win/CS/HandBrakeWPF/defaultsettings.xml +++ b/win/CS/HandBrakeWPF/defaultsettings.xml @@ -465,4 +465,12 @@ false + + + EnableLibHb + + + false + + \ No newline at end of file -- cgit v1.2.3