summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsr55 <[email protected]>2012-08-19 16:43:13 +0000
committersr55 <[email protected]>2012-08-19 16:43:13 +0000
commit4934b148e573ceffad62cbb2e8c09c95a0fe61b3 (patch)
tree5b07f3e8fa74b7f83573746cfe77a9f6c6c2b5ee
parent5ea4bd4112519332f1f420d4fd751bc8829e0509 (diff)
WinGui: Prototype of process isolation support (to be used for libhb when this is fixed up). Uses WCF for process communication.
Initially for the scan service only, encode service proxy coming soon. No changes required for the UI application. Two new implementations of IScan and IEncode will act as a proxy between the UI and the Server Service Layer. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4911 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--win/CS/HandBrake.ApplicationServices/EventArgs/ScanCompletedEventArgs.cs5
-rw-r--r--win/CS/HandBrake.ApplicationServices/EventArgs/ScanProgressEventArgs.cs4
-rw-r--r--win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj6
-rw-r--r--win/CS/HandBrake.ApplicationServices/Parsing/Source.cs11
-rw-r--r--win/CS/HandBrake.ApplicationServices/Parsing/Title.cs33
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/Interfaces/IHbServiceCallback.cs46
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/Interfaces/IServerService.cs93
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/ScanService.cs20
-rw-r--r--win/CS/HandBrake.ApplicationServices/Services/ServerService.cs296
-rw-r--r--win/CS/HandBrake.ApplicationServices/Utilities/GeneralUtilities.cs24
-rw-r--r--win/CS/HandBrake.Server/HandBrake.Server.csproj65
-rw-r--r--win/CS/HandBrake.Server/Program.cs25
-rw-r--r--win/CS/HandBrake.Server/Properties/AssemblyInfo.cs36
-rw-r--r--win/CS/HandBrake.Server/Settings.StyleCop1
-rw-r--r--win/CS/HandBrake10.sln14
-rw-r--r--win/CS/HandBrakeWPF/HandBrakeWPF.csproj9
-rw-r--r--win/CS/HandBrakeWPF/Isolation/BackgroundServiceConnector.cs225
-rw-r--r--win/CS/HandBrakeWPF/Isolation/Interfaces/IIsolatedScanService.cs24
-rw-r--r--win/CS/HandBrakeWPF/Isolation/IsolatedScanService.cs220
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs38
-rw-r--r--win/CS/HandBrakeWPF/Views/MainView.xaml1
21 files changed, 1160 insertions, 36 deletions
diff --git a/win/CS/HandBrake.ApplicationServices/EventArgs/ScanCompletedEventArgs.cs b/win/CS/HandBrake.ApplicationServices/EventArgs/ScanCompletedEventArgs.cs
index 7c9ad7ddd..88a8d9ed2 100644
--- a/win/CS/HandBrake.ApplicationServices/EventArgs/ScanCompletedEventArgs.cs
+++ b/win/CS/HandBrake.ApplicationServices/EventArgs/ScanCompletedEventArgs.cs
@@ -10,10 +10,12 @@
namespace HandBrake.ApplicationServices.EventArgs
{
using System;
+ using System.Runtime.Serialization;
/// <summary>
/// Scan Progress Event Args
/// </summary>
+ [DataContractAttribute]
public class ScanCompletedEventArgs : EventArgs
{
/// <summary>
@@ -38,16 +40,19 @@ namespace HandBrake.ApplicationServices.EventArgs
/// <summary>
/// Gets or sets a value indicating whether Successful.
/// </summary>
+ [DataMember]
public bool Successful { get; set; }
/// <summary>
/// Gets or sets Exception.
/// </summary>
+ [DataMember]
public Exception Exception { get; set; }
/// <summary>
/// Gets or sets ErrorInformation.
/// </summary>
+ [DataMember]
public string ErrorInformation { get; set; }
}
}
diff --git a/win/CS/HandBrake.ApplicationServices/EventArgs/ScanProgressEventArgs.cs b/win/CS/HandBrake.ApplicationServices/EventArgs/ScanProgressEventArgs.cs
index f8d04afae..fd0d01fe3 100644
--- a/win/CS/HandBrake.ApplicationServices/EventArgs/ScanProgressEventArgs.cs
+++ b/win/CS/HandBrake.ApplicationServices/EventArgs/ScanProgressEventArgs.cs
@@ -10,20 +10,24 @@
namespace HandBrake.ApplicationServices.EventArgs
{
using System;
+ using System.Runtime.Serialization;
/// <summary>
/// Scan Progress Event Args
/// </summary>
+ [DataContractAttribute]
public class ScanProgressEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the title currently being scanned.
/// </summary>
+ [DataMember]
public int CurrentTitle { get; set; }
/// <summary>
/// Gets or sets the total number of Titles.
/// </summary>
+ [DataMember]
public int Titles { get; set; }
}
}
diff --git a/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj b/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj
index 4fc9b2fad..04f8149dd 100644
--- a/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj
+++ b/win/CS/HandBrake.ApplicationServices/HandBrake.ApplicationServices.csproj
@@ -79,7 +79,10 @@
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
+ <Reference Include="System.Runtime.Serialization" />
+ <Reference Include="System.ServiceModel" />
<Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
@@ -100,6 +103,9 @@
<Compile Include="EventArgs\ScanCompletedEventArgs.cs" />
<Compile Include="EventArgs\ScanProgressEventArgs.cs" />
<Compile Include="Extensions\StringExtensions.cs" />
+ <Compile Include="Services\Interfaces\IHbServiceCallback.cs" />
+ <Compile Include="Services\Interfaces\IServerService.cs" />
+ <Compile Include="Services\ServerService.cs" />
<Compile Include="Utilities\Converters.cs" />
<Compile Include="Utilities\EnumHelper.cs" />
<Compile Include="Utilities\GrowlCommunicator.cs" />
diff --git a/win/CS/HandBrake.ApplicationServices/Parsing/Source.cs b/win/CS/HandBrake.ApplicationServices/Parsing/Source.cs
index c1eaccc7b..7b63ec149 100644
--- a/win/CS/HandBrake.ApplicationServices/Parsing/Source.cs
+++ b/win/CS/HandBrake.ApplicationServices/Parsing/Source.cs
@@ -11,10 +11,14 @@ namespace HandBrake.ApplicationServices.Parsing
{
using System.Collections.Generic;
using System.IO;
+ using System.Runtime.Serialization;
+
+ using HandBrake.ApplicationServices.Services.Interfaces;
/// <summary>
/// An object representing a scanned DVD
/// </summary>
+ [DataContract]
public class Source
{
/// <summary>
@@ -30,11 +34,13 @@ namespace HandBrake.ApplicationServices.Parsing
/// Gets or sets ScanPath.
/// The Path used by the Scan Service.
/// </summary>
+ [DataMember]
public string ScanPath { get; set; }
/// <summary>
/// Gets or sets Titles. A list of titles from the source
/// </summary>
+ [DataMember]
public List<Title> Titles { get; set; }
/// <summary>
@@ -43,17 +49,18 @@ namespace HandBrake.ApplicationServices.Parsing
/// <param name="output">
/// The output.
/// </param>
+ /// <param name="userSettingService"> </param>
/// <returns>
/// A DVD object which contains a list of title inforamtion
/// </returns>
- public static Source Parse(StreamReader output)
+ public static Source Parse(StreamReader output, IUserSettingService userSettingService)
{
var thisDVD = new Source();
while (!output.EndOfStream)
{
if ((char) output.Peek() == '+')
- thisDVD.Titles.AddRange(Title.ParseList(output.ReadToEnd()));
+ thisDVD.Titles.AddRange(Title.ParseList(output.ReadToEnd(), userSettingService));
else
output.ReadLine();
}
diff --git a/win/CS/HandBrake.ApplicationServices/Parsing/Title.cs b/win/CS/HandBrake.ApplicationServices/Parsing/Title.cs
index a77b84306..f19861cfd 100644
--- a/win/CS/HandBrake.ApplicationServices/Parsing/Title.cs
+++ b/win/CS/HandBrake.ApplicationServices/Parsing/Title.cs
@@ -29,11 +29,6 @@ namespace HandBrake.ApplicationServices.Parsing
public class Title
{
/// <summary>
- /// The User Setting Service
- /// </summary>
- private static IUserSettingService userSettingService = IoC.Get<IUserSettingService>();
-
- /// <summary>
/// Initializes a new instance of the <see cref="Title"/> class.
/// </summary>
public Title()
@@ -125,9 +120,16 @@ namespace HandBrake.ApplicationServices.Parsing
/// <summary>
/// Parse the Title Information
/// </summary>
- /// <param name="output">A StringReader of output data</param>
- /// <returns>A Title Object</returns>
- public static Title Parse(StringReader output)
+ /// <param name="output">
+ /// A StringReader of output data
+ /// </param>
+ /// <param name="userSettingService">
+ /// The user Setting Service.
+ /// </param>
+ /// <returns>
+ /// A Title Object
+ /// </returns>
+ public static Title Parse(StringReader output, IUserSettingService userSettingService)
{
var thisTitle = new Title();
string nextLine = output.ReadLine();
@@ -224,9 +226,16 @@ namespace HandBrake.ApplicationServices.Parsing
/// <summary>
/// Return a list of parsed titles
/// </summary>
- /// <param name="output">The Output</param>
- /// <returns>A List of titles</returns>
- public static Title[] ParseList(string output)
+ /// <param name="output">
+ /// The Output
+ /// </param>
+ /// <param name="userSettingService">
+ /// The user Setting Service.
+ /// </param>
+ /// <returns>
+ /// A List of titles
+ /// </returns>
+ public static Title[] ParseList(string output, IUserSettingService userSettingService)
{
var titles = new List<Title>();
var sr = new StringReader(output);
@@ -237,7 +246,7 @@ namespace HandBrake.ApplicationServices.Parsing
if (sr.Peek() == ' ') // If the character is a space, then chances are it's the combing detected line.
sr.ReadLine(); // Skip over it
else
- titles.Add(Parse(sr));
+ titles.Add(Parse(sr, userSettingService));
}
return titles.ToArray();
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IHbServiceCallback.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IHbServiceCallback.cs
new file mode 100644
index 000000000..afb7ca5c3
--- /dev/null
+++ b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IHbServiceCallback.cs
@@ -0,0 +1,46 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="IHbServiceCallback.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// HandBrake WCF Service Callbacks
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrake.ApplicationServices.Services.Interfaces
+{
+ using System.ServiceModel;
+
+ using HandBrake.ApplicationServices.EventArgs;
+
+ /// <summary>
+ /// HandBrake WCF Service Callbacks
+ /// </summary>
+ [ServiceContract]
+ public interface IHbServiceCallback
+ {
+ /// <summary>
+ /// The scan progress.
+ /// </summary>
+ /// <param name="eventArgs">
+ /// The event args.
+ /// </param>
+ [OperationContract(IsOneWay = true)]
+ void ScanProgressCallback(ScanProgressEventArgs eventArgs);
+
+ /// <summary>
+ /// The scan completed.
+ /// </summary>
+ /// <param name="eventArgs">
+ /// The event args.
+ /// </param>
+ [OperationContract(IsOneWay = true)]
+ void ScanCompletedCallback(ScanCompletedEventArgs eventArgs);
+
+ /// <summary>
+ /// The scan started callback.
+ /// </summary>
+ [OperationContract(IsOneWay = true)]
+ void ScanStartedCallback();
+ }
+}
diff --git a/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IServerService.cs b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IServerService.cs
new file mode 100644
index 000000000..22156e6fc
--- /dev/null
+++ b/win/CS/HandBrake.ApplicationServices/Services/Interfaces/IServerService.cs
@@ -0,0 +1,93 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="IServerService.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Defines the IServerService type.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrake.ApplicationServices.Services.Interfaces
+{
+ using System.Runtime.Serialization;
+ using System.ServiceModel;
+
+ using HandBrake.ApplicationServices.Parsing;
+
+ /// <summary>
+ /// The HandBrakeService interface.
+ /// </summary>
+ [ServiceContract(CallbackContract = typeof(IHbServiceCallback), SessionMode = SessionMode.Required)]
+ public interface IServerService
+ {
+ /// <summary>
+ /// Gets the activity log.
+ /// </summary>
+ [DataMember]
+ string ActivityLog { get; }
+
+ /// <summary>
+ /// Gets the souce data.
+ /// </summary>
+ Source SouceData
+ {
+ [OperationContract]
+ get;
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether is scanning.
+ /// </summary>
+ [DataMember]
+ bool IsScanning { get; }
+
+ /// <summary>
+ /// Start the WCF Service
+ /// </summary>
+ void Start();
+
+ /// <summary>
+ /// Stop the WCF Service
+ /// </summary>
+ void Stop();
+
+ /// <summary>
+ /// The scan source.
+ /// </summary>
+ /// <param name="path">
+ /// The path.
+ /// </param>
+ /// <param name="title">
+ /// The title.
+ /// </param>
+ /// <param name="previewCount">
+ /// The preview Count.
+ /// </param>
+ [OperationContract]
+ void ScanSource(string path, int title, int previewCount);
+
+ /// <summary>
+ /// Stop the scan.
+ /// </summary>
+ [OperationContract]
+ void StopScan();
+
+ /// <summary>
+ /// Subscribe for callbacks from the called functions
+ /// </summary>
+ /// <returns>
+ /// The System.Boolean.
+ /// </returns>
+ [OperationContract]
+ bool Subscribe();
+
+ /// <summary>
+ /// Unsubscribe from callbacks.
+ /// </summary>
+ /// <returns>
+ /// The System.Boolean.
+ /// </returns>
+ [OperationContract]
+ bool Unsubscribe();
+ }
+} \ No newline at end of file
diff --git a/win/CS/HandBrake.ApplicationServices/Services/ScanService.cs b/win/CS/HandBrake.ApplicationServices/Services/ScanService.cs
index 7edbdb320..3e0c36d20 100644
--- a/win/CS/HandBrake.ApplicationServices/Services/ScanService.cs
+++ b/win/CS/HandBrake.ApplicationServices/Services/ScanService.cs
@@ -34,6 +34,11 @@ namespace HandBrake.ApplicationServices.Services
#region Private Variables
/// <summary>
+ /// The User Setting Service
+ /// </summary>
+ private readonly IUserSettingService userSettingService;
+
+ /// <summary>
/// The CLI data parser
/// </summary>
private Parser readData;
@@ -53,18 +58,17 @@ namespace HandBrake.ApplicationServices.Services
/// </summary>
StringBuilder header = GeneralUtilities.CreateCliLogHeader();
- /// <summary>
- /// The User Setting Service
- /// </summary>
- private IUserSettingService userSettingService = IoC.Get<IUserSettingService>();
-
#endregion
/// <summary>
/// Initializes a new instance of the <see cref="ScanService"/> class.
/// </summary>
- public ScanService()
+ /// <param name="userSettingService">
+ /// The user Setting Service.
+ /// </param>
+ public ScanService(IUserSettingService userSettingService)
{
+ this.userSettingService = userSettingService;
this.logBuffer = new StringBuilder();
}
@@ -173,7 +177,7 @@ namespace HandBrake.ApplicationServices.Services
{
StreamReader parseLog = new StreamReader(path);
this.readData = new Parser(parseLog.BaseStream);
- this.SouceData = Source.Parse(this.readData);
+ this.SouceData = Source.Parse(this.readData, this.userSettingService);
this.SouceData.ScanPath = path;
if (this.ScanCompleted != null)
@@ -277,7 +281,7 @@ namespace HandBrake.ApplicationServices.Services
this.readData = new Parser(this.hbProc.StandardError.BaseStream);
this.readData.OnScanProgress += this.OnScanProgress;
- this.SouceData = Source.Parse(this.readData);
+ this.SouceData = Source.Parse(this.readData, this.userSettingService);
this.SouceData.ScanPath = (string)sourcePath;
// Write the Buffer out to file.
diff --git a/win/CS/HandBrake.ApplicationServices/Services/ServerService.cs b/win/CS/HandBrake.ApplicationServices/Services/ServerService.cs
new file mode 100644
index 000000000..025b7c432
--- /dev/null
+++ b/win/CS/HandBrake.ApplicationServices/Services/ServerService.cs
@@ -0,0 +1,296 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="ServerService.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// HandBrake WCF Service
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrake.ApplicationServices.Services
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Runtime.Serialization;
+ using System.ServiceModel;
+ using System.Windows;
+
+ using HandBrake.ApplicationServices.EventArgs;
+ using HandBrake.ApplicationServices.Parsing;
+ using HandBrake.ApplicationServices.Services.Interfaces;
+
+ /// <summary>
+ /// HandBrake WCF Service
+ /// </summary>
+ [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IncludeExceptionDetailInFaults = true, ConcurrencyMode = ConcurrencyMode.Single)]
+ public class ServerService : IServerService
+ {
+ #region Constants and Fields
+
+ /// <summary>
+ /// List of connected Clients. For now, this should only be one.
+ /// </summary>
+ private static readonly List<IHbServiceCallback> Subscribers = new List<IHbServiceCallback>();
+
+ /// <summary>
+ /// The scan service.
+ /// </summary>
+ private static IScan scanService;
+
+ /// <summary>
+ /// The host.
+ /// </summary>
+ private ServiceHost host;
+
+ #endregion
+
+ #region Implemented Interfaces
+
+ #region IServerService
+
+ /// <summary>
+ /// The scan source.
+ /// </summary>
+ /// <param name="path">
+ /// The path.
+ /// </param>
+ /// <param name="title">
+ /// The title.
+ /// </param>
+ /// <param name="previewCount">
+ /// The preview Count.
+ /// </param>
+ public void ScanSource(string path, int title, int previewCount)
+ {
+ Console.WriteLine("Starting Source Scan for: " + path);
+ scanService.ScanStared += this.ScanStaredHandler;
+ scanService.ScanStatusChanged += this.ScanStatusChangedHandler;
+ scanService.ScanCompleted += this.ScanCompletedHandler;
+
+ scanService.Scan(path, title, previewCount, null);
+ }
+
+ /// <summary>
+ /// Gets the activity log.
+ /// </summary>
+ [DataMember]
+ public string ActivityLog
+ {
+ get
+ {
+ return scanService.ActivityLog;
+
+ }
+ }
+
+ /// <summary>
+ /// Gets the souce data.
+ /// </summary>
+ [DataMember]
+ public Source SouceData
+ {
+ get
+ {
+ return scanService.SouceData;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether is scanning.
+ /// </summary>
+ [DataMember]
+ public bool IsScanning
+ {
+ get
+ {
+ return scanService.IsScanning;
+ }
+ }
+
+ /// <summary>
+ /// Start the service
+ /// </summary>
+ public void Start()
+ {
+ using (this.host = new ServiceHost(typeof(ServerService), new Uri("net.tcp://localhost:8000")))
+ {
+ // Setup a listener
+ this.host.AddServiceEndpoint(typeof(IServerService), new NetTcpBinding(), "IHbService");
+ this.host.Open();
+ Console.WriteLine("::: HandBrake Server :::");
+ Console.WriteLine("Service Started");
+
+ // Setup the services we are going to use.
+ scanService = new ScanService(new UserSettingService());
+ Console.ReadLine();
+ }
+ }
+
+ /// <summary>
+ /// Stop this service
+ /// </summary>
+ public void Stop()
+ {
+ if (this.host != null)
+ {
+ this.host.Close();
+ Application.Current.Shutdown();
+ }
+ }
+
+ /// <summary>
+ /// Stop the scan.
+ /// </summary>
+ public void StopScan()
+ {
+ scanService.Stop();
+ }
+
+ /// <summary>
+ /// The subscribe.
+ /// </summary>
+ /// <returns>
+ /// The System.Boolean.
+ /// </returns>
+ public bool Subscribe()
+ {
+ try
+ {
+ // Get the hashCode of the connecting app and store it as a connection
+ var callback = OperationContext.Current.GetCallbackChannel<IHbServiceCallback>();
+ if (!Subscribers.Contains(callback))
+ {
+ Console.WriteLine("Client Connected");
+ Subscribers.Add(callback);
+ }
+ return true;
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// The unsubscribe.
+ /// </summary>
+ /// <returns>
+ /// The System.Boolean.
+ /// </returns>
+ public bool Unsubscribe()
+ {
+ try
+ {
+ var callback = OperationContext.Current.GetCallbackChannel<IHbServiceCallback>();
+ if (Subscribers.Contains(callback))
+ {
+ Subscribers.Remove(callback);
+ if (Subscribers.Count == 0)
+ {
+ Console.WriteLine("Client Disconnected, Shutting down...");
+
+ // Shutdown the service. We no longer have any clients to serve.
+ // It is the responsibility of the UI to maintain a subscription while this service is in use.
+ this.Stop();
+ }
+ }
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Methods
+
+ /// <summary>
+ /// The scan service scan completed event handler
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void ScanCompletedHandler(object sender, ScanCompletedEventArgs e)
+ {
+ Subscribers.ForEach(
+ delegate(IHbServiceCallback callback)
+ {
+ if (((ICommunicationObject)callback).State == CommunicationState.Opened)
+ {
+ Console.WriteLine("Scan Completed Callback");
+ callback.ScanCompletedCallback(e);
+ }
+ else
+ {
+ Subscribers.Remove(callback);
+ }
+ });
+
+ scanService.ScanStared -= this.ScanStaredHandler;
+ scanService.ScanStatusChanged -= this.ScanStatusChangedHandler;
+ scanService.ScanCompleted -= this.ScanCompletedHandler;
+ }
+
+ /// <summary>
+ /// The scan service scan stared.
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void ScanStaredHandler(object sender, EventArgs e)
+ {
+ Subscribers.ForEach(
+ delegate(IHbServiceCallback callback)
+ {
+ if (((ICommunicationObject)callback).State == CommunicationState.Opened)
+ {
+ Console.WriteLine("Scan Started Callback");
+ callback.ScanStartedCallback();
+ }
+ else
+ {
+ Subscribers.Remove(callback);
+ }
+ });
+ }
+
+ /// <summary>
+ /// The scan service scan status changed event handler
+ /// </summary>
+ /// <param name="sender">
+ /// The sender.
+ /// </param>
+ /// <param name="e">
+ /// The e.
+ /// </param>
+ private void ScanStatusChangedHandler(object sender, ScanProgressEventArgs e)
+ {
+ Subscribers.ForEach(
+ delegate(IHbServiceCallback callback)
+ {
+ if (((ICommunicationObject)callback).State == CommunicationState.Opened)
+ {
+ Console.WriteLine("Scan Changed Callback");
+ callback.ScanProgressCallback(e);
+ }
+ else
+ {
+ Subscribers.Remove(callback);
+ }
+ });
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/win/CS/HandBrake.ApplicationServices/Utilities/GeneralUtilities.cs b/win/CS/HandBrake.ApplicationServices/Utilities/GeneralUtilities.cs
index 83ea717e0..696eaedef 100644
--- a/win/CS/HandBrake.ApplicationServices/Utilities/GeneralUtilities.cs
+++ b/win/CS/HandBrake.ApplicationServices/Utilities/GeneralUtilities.cs
@@ -20,6 +20,7 @@ namespace HandBrake.ApplicationServices.Utilities
using Caliburn.Micro;
using HandBrake.ApplicationServices.Model;
+ using HandBrake.ApplicationServices.Services;
using HandBrake.ApplicationServices.Services.Interfaces;
/// <summary>
@@ -34,12 +35,6 @@ namespace HandBrake.ApplicationServices.Utilities
/// </summary>
private static readonly string LogDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) +
"\\HandBrake\\logs";
-
- /// <summary>
- /// The User Setting Service
- /// </summary>
- private static readonly IUserSettingService UserSettingService = IoC.Get<IUserSettingService>();
-
/// <summary>
/// The Instance ID
/// </summary>
@@ -117,12 +112,23 @@ namespace HandBrake.ApplicationServices.Utilities
public static StringBuilder CreateCliLogHeader()
{
var logHeader = new StringBuilder();
+
+ IUserSettingService userSettingService;
+ try
+ {
+ userSettingService = IoC.Get<IUserSettingService>();
+ }
+ catch (Exception)
+ {
+ // TODO Sort this out. Should not be calling IoC.Get or creating a new instance here.
+ userSettingService = new UserSettingService();
+ }
logHeader.AppendLine(
String.Format(
- "HandBrake {0} {1}",
- UserSettingService.GetUserSetting<string>(ASUserSettingConstants.HandBrakeVersion),
- UserSettingService.GetUserSetting<int>(ASUserSettingConstants.HandBrakeBuild)));
+ "HandBrake {0} {1}",
+ userSettingService.GetUserSetting<string>(ASUserSettingConstants.HandBrakeVersion),
+ userSettingService.GetUserSetting<int>(ASUserSettingConstants.HandBrakeBuild)));
logHeader.AppendLine(String.Format("OS: {0}", Environment.OSVersion));
logHeader.AppendLine(String.Format("CPU: {0}", SystemInfo.GetCpuCount));
logHeader.Append(String.Format("Ram: {0} MB, ", SystemInfo.TotalPhysicalMemory));
diff --git a/win/CS/HandBrake.Server/HandBrake.Server.csproj b/win/CS/HandBrake.Server/HandBrake.Server.csproj
new file mode 100644
index 000000000..a6145fd60
--- /dev/null
+++ b/win/CS/HandBrake.Server/HandBrake.Server.csproj
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{36847BA0-6814-41E1-B1C3-1D9D874418E9}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>HandBrake.Server</RootNamespace>
+ <AssemblyName>HandBrake.Server</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <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|x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.ServiceModel" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\HandBrake.ApplicationServices\HandBrake.ApplicationServices.csproj">
+ <Project>{087A2BA8-BAC2-4577-A46F-07FF9D420016}</Project>
+ <Name>HandBrake.ApplicationServices</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(ProgramFiles)\MSBuild\StyleCop\v4.*\StyleCop.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/win/CS/HandBrake.Server/Program.cs b/win/CS/HandBrake.Server/Program.cs
new file mode 100644
index 000000000..baf39e692
--- /dev/null
+++ b/win/CS/HandBrake.Server/Program.cs
@@ -0,0 +1,25 @@
+namespace HandBrake.Server
+{
+ using System;
+
+ using HandBrake.ApplicationServices.Services;
+ using HandBrake.ApplicationServices.Services.Interfaces;
+
+ /// <summary>
+ /// The HandBrake Service
+ /// </summary>
+ class Program
+ {
+ /// <summary>
+ /// The main.
+ /// </summary>
+ /// <param name="args">
+ /// The args.
+ /// </param>
+ static void Main(string[] args)
+ {
+ IServerService server = new ServerService();
+ server.Start();
+ }
+ }
+}
diff --git a/win/CS/HandBrake.Server/Properties/AssemblyInfo.cs b/win/CS/HandBrake.Server/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..4d2e89d86
--- /dev/null
+++ b/win/CS/HandBrake.Server/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HandBrake.Server")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HandBrake.Server")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5d5f700c-a9fb-42d3-ac29-06edf1aecf12")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/win/CS/HandBrake.Server/Settings.StyleCop b/win/CS/HandBrake.Server/Settings.StyleCop
new file mode 100644
index 000000000..bb05f99bc
--- /dev/null
+++ b/win/CS/HandBrake.Server/Settings.StyleCop
@@ -0,0 +1 @@
+<StyleCopSettings Version="105" /> \ No newline at end of file
diff --git a/win/CS/HandBrake10.sln b/win/CS/HandBrake10.sln
index 939940d73..97de9a5d0 100644
--- a/win/CS/HandBrake10.sln
+++ b/win/CS/HandBrake10.sln
@@ -12,6 +12,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
build.xml = build.xml
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HandBrake.Server", "HandBrake.Server\HandBrake.Server.csproj", "{36847BA0-6814-41E1-B1C3-1D9D874418E9}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -64,6 +66,18 @@ Global
{F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}.Release|x64.Build.0 = Release|x64
{F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}.Release|x86.ActiveCfg = Release|x86
{F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}.Release|x86.Build.0 = Release|x86
+ {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|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|x86.ActiveCfg = Release|x86
+ {36847BA0-6814-41E1-B1C3-1D9D874418E9}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
index b9b5a69da..d560cc961 100644
--- a/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
+++ b/win/CS/HandBrakeWPF/HandBrakeWPF.csproj
@@ -95,6 +95,8 @@
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
+ <Reference Include="System.Runtime.Serialization" />
+ <Reference Include="System.ServiceModel" />
<Reference Include="System.Windows.Interactivity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\libraries\caliburn\System.Windows.Interactivity.dll</HintPath>
</Reference>
@@ -127,6 +129,9 @@
<Compile Include="Converters\Options\OptionsTabConverter.cs" />
<Compile Include="Converters\Subtitles\SubtitlesQueueDisplayConverter.cs" />
<Compile Include="Converters\Video\VideoEncoderConverter.cs" />
+ <Compile Include="Isolation\BackgroundServiceConnector.cs" />
+ <Compile Include="Isolation\Interfaces\IIsolatedScanService.cs" />
+ <Compile Include="Isolation\IsolatedScanService.cs" />
<Compile Include="Services\DriveDetectService.cs" />
<Compile Include="Services\Interfaces\IDriveDetectService.cs" />
<Compile Include="Model\ShellWindow.cs" />
@@ -420,6 +425,10 @@
<Project>{F0A61F62-2C3B-4A87-AFF4-0C4256253DA1}</Project>
<Name>HandBrakeInterop</Name>
</ProjectReference>
+ <ProjectReference Include="..\HandBrake.Server\HandBrake.Server.csproj">
+ <Project>{36847BA0-6814-41E1-B1C3-1D9D874418E9}</Project>
+ <Name>HandBrake.Server</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
diff --git a/win/CS/HandBrakeWPF/Isolation/BackgroundServiceConnector.cs b/win/CS/HandBrakeWPF/Isolation/BackgroundServiceConnector.cs
new file mode 100644
index 000000000..b6198da46
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Isolation/BackgroundServiceConnector.cs
@@ -0,0 +1,225 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="BackgroundServiceConnector.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Background Service Connector.
+// HandBrake has the ability to connect to a service app that will control HandBrakeCLI or Libhb.
+// This acts as process isolation.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+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;
+
+ /// <summary>
+ /// Background Service Connector.
+ /// HandBrake has the ability to connect to a service app that will control HandBrakeCLI or Libhb.
+ /// This acts as process isolation.
+ /// </summary>
+ public class BackgroundServiceConnector : IHbServiceCallback, IDisposable
+ {
+ /// <summary>
+ /// The error service.
+ /// </summary>
+ private readonly IErrorService errorService;
+
+ #region Constants and Fields
+
+ /// <summary>
+ /// Gets or sets the pipe factory.
+ /// DuplexChannelFactory is necessary for Callbacks.
+ /// </summary>
+ private DuplexChannelFactory<IServerService> pipeFactory;
+
+ /// <summary>
+ /// The background process.
+ /// </summary>
+ private Process backgroundProcess;
+
+ #endregion
+
+ #region Properties
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BackgroundServiceConnector"/> class.
+ /// </summary>
+ /// <param name="errorService">
+ /// The error service.
+ /// </param>
+ public BackgroundServiceConnector(IErrorService errorService)
+ {
+ this.errorService = errorService;
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether is connected.
+ /// </summary>
+ public bool IsConnected { get; set; }
+
+ /// <summary>
+ /// Gets or sets the service.
+ /// </summary>
+ public IServerService Service { get; set; }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// The can connect.
+ /// </summary>
+ /// <returns>
+ /// The System.Boolean.
+ /// </returns>
+ public bool CanConnect()
+ {
+ return true;
+ }
+
+ /// <summary>
+ /// The connect.
+ /// </summary>
+ public void Connect()
+ {
+ ThreadPool.QueueUserWorkItem(delegate
+ {
+ try
+ {
+ this.pipeFactory = new DuplexChannelFactory<IServerService>(
+ new InstanceContext(this),
+ new NetTcpBinding(),
+ new EndpointAddress("net.tcp://127.0.0.1:8000/IHbService"));
+
+ // Connect and Subscribe to the Server
+ this.Service = this.pipeFactory.CreateChannel();
+ this.Service.Subscribe();
+ this.IsConnected = true;
+ }
+ catch (Exception exc)
+ {
+ Caliburn.Micro.Execute.OnUIThread(() => this.errorService.ShowError("Unable to connect to background worker service", "Please restart HandBrake", exc));
+ }
+ });
+ }
+
+ /// <summary>
+ /// The disconnect.
+ /// </summary>
+ public void Disconnect()
+ {
+ if (backgroundProcess != null && !backgroundProcess.HasExited)
+ {
+ try
+ {
+ this.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);
+ }
+ }
+ }
+
+ /// <summary>
+ /// The scan source.
+ /// </summary>
+ /// <param name="path">
+ /// The path.
+ /// </param>
+ /// <param name="title">
+ /// The title.
+ /// </param>
+ /// <param name="previewCount">
+ /// The preview count.
+ /// </param>
+ public void ScanSource(string path, int title, int previewCount)
+ {
+ ThreadPool.QueueUserWorkItem(delegate { this.Service.ScanSource(path, title, previewCount); });
+ }
+
+ /// <summary>
+ /// The start server.
+ /// </summary>
+ public void StartServer()
+ {
+ if (this.backgroundProcess == null)
+ {
+ this.backgroundProcess = Process.Start("HandBrake.Server.exe");
+ }
+ }
+
+ #endregion
+
+ #region Implemented Interfaces
+
+ #region IDisposable
+
+ /// <summary>
+ /// The dispose.
+ /// </summary>
+ public void Dispose()
+ {
+ this.Service.Unsubscribe();
+ }
+
+ #endregion
+
+ #region IHbServiceCallback
+
+ /// <summary>
+ /// The scan completed.
+ /// </summary>
+ /// <param name="eventArgs">
+ /// The event args.
+ /// </param>
+ public virtual void ScanCompletedCallback(ScanCompletedEventArgs eventArgs)
+ {
+ }
+
+ /// <summary>
+ /// The scan progress.
+ /// </summary>
+ /// <param name="eventArgs">
+ /// The event args.
+ /// </param>
+ public virtual void ScanProgressCallback(ScanProgressEventArgs eventArgs)
+ {
+ }
+
+ /// <summary>
+ /// The scan started callback.
+ /// </summary>
+ public virtual void ScanStartedCallback()
+ {
+ }
+
+ #endregion
+
+ #endregion
+
+ #region Implementation of IHbServiceCallback
+
+ /// <summary>
+ /// The test.
+ /// </summary>
+ /// <param name="message">
+ /// The message.
+ /// </param>
+ public void Test(string message)
+ {
+ Console.WriteLine(message);
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Isolation/Interfaces/IIsolatedScanService.cs b/win/CS/HandBrakeWPF/Isolation/Interfaces/IIsolatedScanService.cs
new file mode 100644
index 000000000..7b94deb58
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Isolation/Interfaces/IIsolatedScanService.cs
@@ -0,0 +1,24 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="IIsolatedScanService.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// The Isolated Scan Service interface.
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace HandBrakeWPF.Isolation.Interfaces
+{
+ using HandBrake.ApplicationServices.Services.Interfaces;
+
+ /// <summary>
+ /// The Isolated Scan Service interface.
+ /// </summary>
+ public interface IIsolatedScanService : IScan
+ {
+ /// <summary>
+ /// The disconnect.
+ /// </summary>
+ void Disconnect();
+ }
+} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Isolation/IsolatedScanService.cs b/win/CS/HandBrakeWPF/Isolation/IsolatedScanService.cs
new file mode 100644
index 000000000..01153d2c6
--- /dev/null
+++ b/win/CS/HandBrakeWPF/Isolation/IsolatedScanService.cs
@@ -0,0 +1,220 @@
+// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="IsolatedScanService.cs" company="HandBrake Project (http://handbrake.fr)">
+// This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License.
+// </copyright>
+// <summary>
+// Isolated Scan Service
+// This is an implementation of the IScan implementation that runs scans on a seperate process
+// </summary>
+// --------------------------------------------------------------------------------------------------------------------
+
+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;
+
+ /// <summary>
+ /// Isolated Scan Service.
+ /// This is an implementation of the IScan implementation that runs scans on a seperate process
+ /// </summary>
+ public class IsolatedScanService : BackgroundServiceConnector, IIsolatedScanService
+ {
+ #region Constants and Fields
+
+ /// <summary>
+ /// The post action.
+ /// </summary>
+ private Action<bool> postScanAction;
+
+ #endregion
+
+ #region Events
+
+ /// <summary>
+ /// The scan completed.
+ /// </summary>
+ public event ScanCompletedStatus ScanCompleted;
+
+ /// <summary>
+ /// The scan stared.
+ /// </summary>
+ public event EventHandler ScanStared;
+
+ /// <summary>
+ /// The scan status changed.
+ /// </summary>
+ public event ScanProgessStatus ScanStatusChanged;
+
+ #endregion
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="IsolatedScanService"/> class.
+ /// </summary>
+ /// <param name="errorService">
+ /// The error Service.
+ /// </param>
+ public IsolatedScanService(IErrorService errorService) : base(errorService)
+ {
+ try
+ {
+ if (this.CanConnect())
+ {
+ this.StartServer();
+ this.Connect();
+ }
+ }
+ catch (Exception exception)
+ {
+ errorService.ShowError(
+ "Unable to connect to scan worker process.", "Try restarting HandBrake", exception);
+ }
+ }
+
+ #region Properties
+
+ /// <summary>
+ /// Gets ActivityLog.
+ /// </summary>
+ public string ActivityLog
+ {
+ get
+ {
+ return this.Service.ActivityLog;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether IsScanning.
+ /// </summary>
+ public bool IsScanning
+ {
+ get
+ {
+ return this.Service.IsScanning;
+ }
+ }
+
+ /// <summary>
+ /// Gets the Souce Data.
+ /// </summary>
+ public Source SouceData
+ {
+ get
+ {
+ return this.Service.SouceData;
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// The scan completed callback.
+ /// </summary>
+ /// <param name="eventArgs">
+ /// The event args.
+ /// </param>
+ 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);
+ }
+
+ /// <summary>
+ /// The scan progress callback.
+ /// </summary>
+ /// <param name="eventArgs">
+ /// The event args.
+ /// </param>
+ public override void ScanProgressCallback(ScanProgressEventArgs eventArgs)
+ {
+ if (this.ScanStatusChanged != null)
+ {
+ ThreadPool.QueueUserWorkItem(delegate { this.ScanStatusChanged(this, eventArgs); });
+ }
+
+ base.ScanProgressCallback(eventArgs);
+ }
+
+ /// <summary>
+ /// The scan started callback.
+ /// </summary>
+ public override void ScanStartedCallback()
+ {
+ if (this.ScanStared != null)
+ {
+ ThreadPool.QueueUserWorkItem(delegate { this.ScanStared(this, EventArgs.Empty); });
+ }
+
+ base.ScanStartedCallback();
+ }
+
+ #endregion
+
+ #region Implemented Interfaces
+
+ #region IScan
+
+ /// <summary>
+ /// Take a Scan Log file, and process it as if it were from the CLI.
+ /// </summary>
+ /// <param name="path">
+ /// The path to the log file.
+ /// </param>
+ public void DebugScanLog(string path)
+ {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Scan a Source Path.
+ /// Title 0: scan all
+ /// </summary>
+ /// <param name="sourcePath">
+ /// Path to the file to scan
+ /// </param>
+ /// <param name="title">
+ /// int title number. 0 for scan all
+ /// </param>
+ /// <param name="previewCount">
+ /// The preview Count.
+ /// </param>
+ /// <param name="postAction">
+ /// The post Action.
+ /// </param>
+ public void Scan(string sourcePath, int title, int previewCount, Action<bool> postAction)
+ {
+ this.postScanAction = postAction;
+ this.Service.ScanSource(sourcePath, title, previewCount);
+ }
+
+ /// <summary>
+ /// Kill the scan
+ /// </summary>
+ public void Stop()
+ {
+ throw new NotImplementedException();
+ }
+
+ #endregion
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
index 606d87a96..3fc83ddac 100644
--- a/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/MainViewModel.cs
@@ -29,6 +29,8 @@ 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;
@@ -48,7 +50,7 @@ namespace HandBrakeWPF.ViewModels
/// <summary>
/// The Source Scan Service.
/// </summary>
- private readonly IScan scanService;
+ private IScan scanService;
/// <summary>
/// The Encode Service
@@ -198,7 +200,6 @@ namespace HandBrakeWPF.ViewModels
{
GeneralUtilities.SetInstanceId();
-
this.scanService = scanService;
this.encodeService = encodeService;
this.presetService = presetService;
@@ -819,6 +820,13 @@ 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();
+ }
+
// Unsubscribe from Events.
this.scanService.ScanStared -= this.ScanStared;
this.scanService.ScanCompleted -= this.ScanCompleted;
@@ -1133,6 +1141,26 @@ namespace HandBrakeWPF.ViewModels
}
}
+ /// <summary>
+ /// The test isolation services.
+ /// Swaps out the implementation of IScan to the IsolatedScanService version.
+ /// </summary>
+ public void TestIsolationServices()
+ {
+ // Unhook the old service
+ this.scanService.ScanStared -= this.ScanStared;
+ this.scanService.ScanCompleted -= this.ScanCompleted;
+ this.scanService.ScanStatusChanged -= this.ScanStatusChanged;
+
+ // Replace the Service
+ this.scanService = new IsolatedScanService(this.errorService);
+
+ // Add Event Hooks
+ this.scanService.ScanStared += this.ScanStared;
+ this.scanService.ScanCompleted += this.ScanCompleted;
+ this.scanService.ScanStatusChanged += this.ScanStatusChanged;
+ }
+
#endregion
#region Main Window Public Methods
@@ -1562,19 +1590,19 @@ namespace HandBrakeWPF.ViewModels
/// </param>
private void ScanCompleted(object sender, HandBrake.ApplicationServices.EventArgs.ScanCompletedEventArgs e)
{
+ this.scanService.SouceData.CopyTo(this.ScannedSource);
Execute.OnUIThread(() =>
{
if (e.Successful)
{
- this.scanService.SouceData.CopyTo(this.ScannedSource);
this.NotifyOfPropertyChange("ScannedSource");
this.NotifyOfPropertyChange("ScannedSource.Titles");
this.SelectedTitle = this.ScannedSource.Titles.FirstOrDefault(t => t.MainTitle)
?? this.ScannedSource.Titles.FirstOrDefault();
- this.SetupTabs();
- this.ShowStatusWindow = false;
+ this.SetupTabs();
}
+ this.ShowStatusWindow = false;
this.SourceLabel = "Scan Completed";
this.StatusLabel = "Scan Completed";
});
diff --git a/win/CS/HandBrakeWPF/Views/MainView.xaml b/win/CS/HandBrakeWPF/Views/MainView.xaml
index 57e7beee4..c7f6c14c4 100644
--- a/win/CS/HandBrakeWPF/Views/MainView.xaml
+++ b/win/CS/HandBrakeWPF/Views/MainView.xaml
@@ -134,6 +134,7 @@
<MenuItem Header="Debug" Foreground="Transparent" >
<MenuItem Header="Show CLI Equiv" Micro:Message.Attach="[Event Click] = [Action ShowCliQuery]" />
<MenuItem Header="Debug Scan Log" Micro:Message.Attach="[Event Click] = [Action DebugScanLog]" />
+ <MenuItem Header="Test Isolation Service" Micro:Message.Attach="[Event Click] = [Action TestIsolationServices]" />
</MenuItem>
</Menu>