summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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>