aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Common
diff options
context:
space:
mode:
authorLukePulverenti <luke.pulverenti@gmail.com>2013-02-21 23:23:06 -0500
committerLukePulverenti <luke.pulverenti@gmail.com>2013-02-21 23:23:06 -0500
commit868a7ce9c8b50bd64c8b5ae33fec77abfd25ef7c (patch)
treea60a3a27afe43a8b5e3412279225be7b2415e6c3 /MediaBrowser.Common
parentfdafa596832eae13cebcf5bbe5fa867f7ba068f0 (diff)
isolated clickonce dependancies
Diffstat (limited to 'MediaBrowser.Common')
-rw-r--r--MediaBrowser.Common/Api/Logging/LogFileWebSocketListener.cs146
-rw-r--r--MediaBrowser.Common/Api/ScheduledTasks/ScheduledTaskService.cs176
-rw-r--r--MediaBrowser.Common/Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs49
-rw-r--r--MediaBrowser.Common/Api/SystemInfoWebSocketListener.cs44
-rw-r--r--MediaBrowser.Common/Extensions/BaseExtensions.cs19
-rw-r--r--MediaBrowser.Common/Kernel/BaseKernel.cs19
-rw-r--r--MediaBrowser.Common/Kernel/IApplicationHost.cs30
-rw-r--r--MediaBrowser.Common/Kernel/TcpManager.cs11
-rw-r--r--MediaBrowser.Common/MediaBrowser.Common.csproj17
-rw-r--r--MediaBrowser.Common/Net/HttpServer.cs15
-rw-r--r--MediaBrowser.Common/Net/NetworkShares.cs644
-rw-r--r--MediaBrowser.Common/Net/StaticResult.cs14
-rw-r--r--MediaBrowser.Common/Resources/Images/Icon.icobin149571 -> 0 bytes
-rw-r--r--MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs8
-rw-r--r--MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs2
-rw-r--r--MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs2
-rw-r--r--MediaBrowser.Common/ScheduledTasks/Tasks/DeleteCacheFileTask.cs8
-rw-r--r--MediaBrowser.Common/ScheduledTasks/Tasks/DeleteLogFileTask.cs6
-rw-r--r--MediaBrowser.Common/ScheduledTasks/Tasks/ReloadLoggerTask.cs4
-rw-r--r--MediaBrowser.Common/ScheduledTasks/Tasks/SystemUpdateTask.cs42
-rw-r--r--MediaBrowser.Common/Updates/ApplicationUpdateCheck.cs92
-rw-r--r--MediaBrowser.Common/Updates/ApplicationUpdater.cs93
-rw-r--r--MediaBrowser.Common/Updates/ClickOnceHelper.cs217
23 files changed, 104 insertions, 1554 deletions
diff --git a/MediaBrowser.Common/Api/Logging/LogFileWebSocketListener.cs b/MediaBrowser.Common/Api/Logging/LogFileWebSocketListener.cs
deleted file mode 100644
index e873facb1..000000000
--- a/MediaBrowser.Common/Api/Logging/LogFileWebSocketListener.cs
+++ /dev/null
@@ -1,146 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Kernel;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-using MediaBrowser.Model.Logging;
-
-namespace MediaBrowser.Common.Api.Logging
-{
- /// <summary>
- /// Class ScheduledTasksWebSocketListener
- /// </summary>
- [Export(typeof(IWebSocketListener))]
- public class LogFileWebSocketListener : BasePeriodicWebSocketListener<IKernel, IEnumerable<string>, LogFileWebSocketState>
- {
- /// <summary>
- /// Gets the name.
- /// </summary>
- /// <value>The name.</value>
- protected override string Name
- {
- get { return "LogFile"; }
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="LogFileWebSocketListener" /> class.
- /// </summary>
- /// <param name="logger">The logger.</param>
- [ImportingConstructor]
- public LogFileWebSocketListener([Import("logger")] ILogger logger)
- : base(logger)
- {
-
- }
-
- /// <summary>
- /// Initializes the specified kernel.
- /// </summary>
- /// <param name="kernel">The kernel.</param>
- public override void Initialize(IKernel kernel)
- {
- base.Initialize(kernel);
-
- kernel.LoggerLoaded += kernel_LoggerLoaded;
- }
-
- /// <summary>
- /// Gets the data to send.
- /// </summary>
- /// <param name="state">The state.</param>
- /// <returns>IEnumerable{System.String}.</returns>
- protected override async Task<IEnumerable<string>> GetDataToSend(LogFileWebSocketState state)
- {
- if (!string.Equals(Kernel.LogFilePath, state.LastLogFilePath))
- {
- state.LastLogFilePath = Kernel.LogFilePath;
- state.StartLine = 0;
- }
-
- var lines = await GetLogLines(state.LastLogFilePath, state.StartLine).ConfigureAwait(false);
-
- state.StartLine += lines.Count;
-
- return lines;
- }
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected override void Dispose(bool dispose)
- {
- if (dispose)
- {
- Kernel.LoggerLoaded -= kernel_LoggerLoaded;
- }
- base.Dispose(dispose);
- }
-
- /// <summary>
- /// Handles the LoggerLoaded event of the kernel control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
- void kernel_LoggerLoaded(object sender, EventArgs e)
- {
- // Reset the startline for each connection whenever the logger reloads
- lock (ActiveConnections)
- {
- foreach (var connection in ActiveConnections)
- {
- connection.Item4.StartLine = 0;
- }
- }
- }
-
- /// <summary>
- /// Gets the log lines.
- /// </summary>
- /// <param name="logFilePath">The log file path.</param>
- /// <param name="startLine">The start line.</param>
- /// <returns>Task{IEnumerable{System.String}}.</returns>
- internal static async Task<List<string>> GetLogLines(string logFilePath, int startLine)
- {
- var lines = new List<string>();
-
- using (var fs = new FileStream(logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, StreamDefaults.DefaultFileStreamBufferSize, true))
- {
- using (var reader = new StreamReader(fs))
- {
- while (!reader.EndOfStream)
- {
- lines.Add(await reader.ReadLineAsync().ConfigureAwait(false));
- }
- }
- }
-
- if (startLine > 0)
- {
- lines = lines.Skip(startLine).ToList();
- }
-
- return lines;
- }
- }
-
- /// <summary>
- /// Class LogFileWebSocketState
- /// </summary>
- public class LogFileWebSocketState
- {
- /// <summary>
- /// Gets or sets the last log file path.
- /// </summary>
- /// <value>The last log file path.</value>
- public string LastLogFilePath { get; set; }
- /// <summary>
- /// Gets or sets the start line.
- /// </summary>
- /// <value>The start line.</value>
- public int StartLine { get; set; }
- }
-}
diff --git a/MediaBrowser.Common/Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Common/Api/ScheduledTasks/ScheduledTaskService.cs
deleted file mode 100644
index 1df24dcd2..000000000
--- a/MediaBrowser.Common/Api/ScheduledTasks/ScheduledTaskService.cs
+++ /dev/null
@@ -1,176 +0,0 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Common.ScheduledTasks;
-using MediaBrowser.Common.Serialization;
-using MediaBrowser.Model.Tasks;
-using ServiceStack.ServiceHost;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.IO;
-using System.Linq;
-using ServiceStack.Text.Controller;
-
-namespace MediaBrowser.Common.Api.ScheduledTasks
-{
- /// <summary>
- /// Class GetScheduledTask
- /// </summary>
- [Route("/ScheduledTasks/{Id}", "GET")]
- public class GetScheduledTask : IReturn<TaskInfo>
- {
- /// <summary>
- /// Gets or sets the id.
- /// </summary>
- /// <value>The id.</value>
- public Guid Id { get; set; }
- }
-
- /// <summary>
- /// Class GetScheduledTasks
- /// </summary>
- [Route("/ScheduledTasks", "GET")]
- public class GetScheduledTasks : IReturn<List<TaskInfo>>
- {
-
- }
-
- /// <summary>
- /// Class StartScheduledTask
- /// </summary>
- [Route("/ScheduledTasks/Running/{Id}", "POST")]
- public class StartScheduledTask : IReturnVoid
- {
- /// <summary>
- /// Gets or sets the id.
- /// </summary>
- /// <value>The id.</value>
- public Guid Id { get; set; }
- }
-
- /// <summary>
- /// Class StopScheduledTask
- /// </summary>
- [Route("/ScheduledTasks/Running/{Id}", "DELETE")]
- public class StopScheduledTask : IReturnVoid
- {
- /// <summary>
- /// Gets or sets the id.
- /// </summary>
- /// <value>The id.</value>
- public Guid Id { get; set; }
- }
-
- /// <summary>
- /// Class UpdateScheduledTaskTriggers
- /// </summary>
- [Route("/ScheduledTasks/{Id}/Triggers", "POST")]
- public class UpdateScheduledTaskTriggers : IRequiresRequestStream
- {
- /// <summary>
- /// Gets or sets the task id.
- /// </summary>
- /// <value>The task id.</value>
- public Guid Id { get; set; }
-
- /// <summary>
- /// The raw Http Request Input Stream
- /// </summary>
- /// <value>The request stream.</value>
- public Stream RequestStream { get; set; }
- }
-
- /// <summary>
- /// Class ScheduledTasksService
- /// </summary>
- [Export(typeof(IRestfulService))]
- public class ScheduledTaskService : BaseRestService
- {
- /// <summary>
- /// Gets the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- /// <returns>IEnumerable{TaskInfo}.</returns>
- public object Get(GetScheduledTasks request)
- {
- var result = Kernel.ScheduledTasks.OrderBy(i => i.Name)
- .Select(ScheduledTaskHelpers.GetTaskInfo).ToList();
-
- return ToOptimizedResult(result);
- }
-
- /// <summary>
- /// Gets the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- /// <returns>IEnumerable{TaskInfo}.</returns>
- public object Get(GetScheduledTask request)
- {
- var task = Kernel.ScheduledTasks.FirstOrDefault(i => i.Id == request.Id);
-
- if (task == null)
- {
- throw new ResourceNotFoundException("Task not found");
- }
-
- var result = ScheduledTaskHelpers.GetTaskInfo(task);
-
- return ToOptimizedResult(result);
- }
-
- /// <summary>
- /// Posts the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- public void Post(StartScheduledTask request)
- {
- var task = Kernel.ScheduledTasks.FirstOrDefault(i => i.Id == request.Id);
-
- if (task == null)
- {
- throw new ResourceNotFoundException("Task not found");
- }
-
- task.Execute();
- }
-
- /// <summary>
- /// Posts the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- public void Delete(StopScheduledTask request)
- {
- var task = Kernel.ScheduledTasks.FirstOrDefault(i => i.Id == request.Id);
-
- if (task == null)
- {
- throw new ResourceNotFoundException("Task not found");
- }
-
- task.Cancel();
- }
-
- /// <summary>
- /// Posts the specified request.
- /// </summary>
- /// <param name="request">The request.</param>
- public void Post(UpdateScheduledTaskTriggers request)
- {
- // We need to parse this manually because we told service stack not to with IRequiresRequestStream
- // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs
- var pathInfo = PathInfo.Parse(Request.PathInfo);
- var id = new Guid(pathInfo.GetArgumentValue<string>(1));
-
- var task = Kernel.ScheduledTasks.FirstOrDefault(i => i.Id == id);
-
- if (task == null)
- {
- throw new ResourceNotFoundException("Task not found");
- }
-
- var triggerInfos = JsonSerializer.DeserializeFromStream<TaskTriggerInfo[]>(request.RequestStream);
-
- task.Triggers = triggerInfos.Select(t => ScheduledTaskHelpers.GetTrigger(t, Kernel));
- }
- }
-}
diff --git a/MediaBrowser.Common/Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs b/MediaBrowser.Common/Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs
deleted file mode 100644
index 7e4596d9d..000000000
--- a/MediaBrowser.Common/Api/ScheduledTasks/ScheduledTasksWebSocketListener.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.ScheduledTasks;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Model.Tasks;
-using System.Collections.Generic;
-using System.ComponentModel.Composition;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Common.Api.ScheduledTasks
-{
- /// <summary>
- /// Class ScheduledTasksWebSocketListener
- /// </summary>
- [Export(typeof(IWebSocketListener))]
- public class ScheduledTasksWebSocketListener : BasePeriodicWebSocketListener<IKernel, IEnumerable<TaskInfo>, object>
- {
- /// <summary>
- /// Gets the name.
- /// </summary>
- /// <value>The name.</value>
- protected override string Name
- {
- get { return "ScheduledTasksInfo"; }
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="ScheduledTasksWebSocketListener" /> class.
- /// </summary>
- /// <param name="logger">The logger.</param>
- [ImportingConstructor]
- public ScheduledTasksWebSocketListener([Import("logger")] ILogger logger)
- : base(logger)
- {
-
- }
-
- /// <summary>
- /// Gets the data to send.
- /// </summary>
- /// <param name="state">The state.</param>
- /// <returns>Task{IEnumerable{TaskInfo}}.</returns>
- protected override Task<IEnumerable<TaskInfo>> GetDataToSend(object state)
- {
- return Task.FromResult(Kernel.ScheduledTasks.OrderBy(i => i.Name)
- .Select(ScheduledTaskHelpers.GetTaskInfo));
- }
- }
-}
diff --git a/MediaBrowser.Common/Api/SystemInfoWebSocketListener.cs b/MediaBrowser.Common/Api/SystemInfoWebSocketListener.cs
deleted file mode 100644
index a216937ed..000000000
--- a/MediaBrowser.Common/Api/SystemInfoWebSocketListener.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using MediaBrowser.Common.Kernel;
-using MediaBrowser.Model.Logging;
-using System.ComponentModel.Composition;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Common.Api
-{
- /// <summary>
- /// Class SystemInfoWebSocketListener
- /// </summary>
- [Export(typeof(IWebSocketListener))]
- public class SystemInfoWebSocketListener : BasePeriodicWebSocketListener<IKernel, Model.System.SystemInfo, object>
- {
- /// <summary>
- /// Gets the name.
- /// </summary>
- /// <value>The name.</value>
- protected override string Name
- {
- get { return "SystemInfo"; }
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="SystemInfoWebSocketListener" /> class.
- /// </summary>
- /// <param name="logger">The logger.</param>
- [ImportingConstructor]
- public SystemInfoWebSocketListener([Import("logger")] ILogger logger)
- : base(logger)
- {
-
- }
-
- /// <summary>
- /// Gets the data to send.
- /// </summary>
- /// <param name="state">The state.</param>
- /// <returns>Task{SystemInfo}.</returns>
- protected override Task<Model.System.SystemInfo> GetDataToSend(object state)
- {
- return Task.FromResult(Kernel.GetSystemInfo());
- }
- }
-}
diff --git a/MediaBrowser.Common/Extensions/BaseExtensions.cs b/MediaBrowser.Common/Extensions/BaseExtensions.cs
index e6b9d8ee6..6abe6d4e0 100644
--- a/MediaBrowser.Common/Extensions/BaseExtensions.cs
+++ b/MediaBrowser.Common/Extensions/BaseExtensions.cs
@@ -5,7 +5,6 @@ using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
-using System.Windows.Threading;
namespace MediaBrowser.Common.Extensions
{
@@ -47,24 +46,6 @@ namespace MediaBrowser.Common.Extensions
}
/// <summary>
- /// Invokes an action after a specified delay
- /// </summary>
- /// <param name="dispatcher">The dispatcher.</param>
- /// <param name="action">The action.</param>
- /// <param name="delayMs">The delay ms.</param>
- public static void InvokeWithDelay(this Dispatcher dispatcher, Action action, long delayMs)
- {
- var timer = new DispatcherTimer(DispatcherPriority.Normal, dispatcher);
- timer.Interval = TimeSpan.FromMilliseconds(delayMs);
- timer.Tick += (sender, args) =>
- {
- timer.Stop();
- action();
- };
- timer.Start();
- }
-
- /// <summary>
/// Provides a non-blocking method to start a process and wait asynchronously for it to exit
/// </summary>
/// <param name="process">The process.</param>
diff --git a/MediaBrowser.Common/Kernel/BaseKernel.cs b/MediaBrowser.Common/Kernel/BaseKernel.cs
index a4ac70749..d172d0a0d 100644
--- a/MediaBrowser.Common/Kernel/BaseKernel.cs
+++ b/MediaBrowser.Common/Kernel/BaseKernel.cs
@@ -13,7 +13,6 @@ using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
-using System.Deployment.Application;
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -156,12 +155,6 @@ namespace MediaBrowser.Common.Kernel
public bool IsFirstRun { get; private set; }
/// <summary>
- /// The version of the application to display
- /// </summary>
- /// <value>The display version.</value>
- public string DisplayVersion { get { return ApplicationVersion.ToString(); } }
-
- /// <summary>
/// Gets or sets a value indicating whether this instance has changes that require the entire application to restart.
/// </summary>
/// <value><c>true</c> if this instance has pending application restart; otherwise, <c>false</c>.</value>
@@ -325,7 +318,10 @@ namespace MediaBrowser.Common.Kernel
/// Gets the log file path.
/// </summary>
/// <value>The log file path.</value>
- public string LogFilePath { get; private set; }
+ public string LogFilePath
+ {
+ get { return ApplicationHost.LogFilePath; }
+ }
/// <summary>
/// Gets the logger.
@@ -429,7 +425,7 @@ namespace MediaBrowser.Common.Kernel
await ReloadComposableParts().ConfigureAwait(false);
DisposeTcpManager();
- TcpManager = new TcpManager(this, Logger);
+ TcpManager = new TcpManager(ApplicationHost, this, Logger);
}
/// <summary>
@@ -482,6 +478,7 @@ namespace MediaBrowser.Common.Kernel
protected virtual void ComposeExportedValues(CompositionContainer container)
{
container.ComposeExportedValue("logger", Logger);
+ container.ComposeExportedValue("appHost", ApplicationHost);
}
/// <summary>
@@ -729,8 +726,8 @@ namespace MediaBrowser.Common.Kernel
return new SystemInfo
{
HasPendingRestart = HasPendingRestart,
- Version = DisplayVersion,
- IsNetworkDeployed = ApplicationDeployment.IsNetworkDeployed,
+ Version = ApplicationVersion.ToString(),
+ IsNetworkDeployed = ApplicationHost.CanSelfUpdate,
WebSocketPortNumber = TcpManager.WebSocketPortNumber,
SupportsNativeWebSocket = TcpManager.SupportsNativeWebSocket,
FailedPluginAssemblies = FailedPluginAssemblies.ToArray()
diff --git a/MediaBrowser.Common/Kernel/IApplicationHost.cs b/MediaBrowser.Common/Kernel/IApplicationHost.cs
index c1b63c261..63c63eb3d 100644
--- a/MediaBrowser.Common/Kernel/IApplicationHost.cs
+++ b/MediaBrowser.Common/Kernel/IApplicationHost.cs
@@ -1,4 +1,8 @@
-
+using MediaBrowser.Model.Updates;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
namespace MediaBrowser.Common.Kernel
{
/// <summary>
@@ -15,5 +19,29 @@ namespace MediaBrowser.Common.Kernel
/// Reloads the logger.
/// </summary>
void ReloadLogger();
+
+ /// <summary>
+ /// Gets the log file path.
+ /// </summary>
+ /// <value>The log file path.</value>
+ string LogFilePath { get; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance can self update.
+ /// </summary>
+ /// <value><c>true</c> if this instance can self update; otherwise, <c>false</c>.</value>
+ bool CanSelfUpdate { get; }
+
+ /// <summary>
+ /// Checks for update.
+ /// </summary>
+ /// <returns>Task{CheckForUpdateResult}.</returns>
+ Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress<double> progress);
+
+ /// <summary>
+ /// Updates the application.
+ /// </summary>
+ /// <returns>Task.</returns>
+ Task UpdateApplication(CancellationToken cancellationToken, IProgress<double> progress);
}
}
diff --git a/MediaBrowser.Common/Kernel/TcpManager.cs b/MediaBrowser.Common/Kernel/TcpManager.cs
index 7fb624f73..086815cbf 100644
--- a/MediaBrowser.Common/Kernel/TcpManager.cs
+++ b/MediaBrowser.Common/Kernel/TcpManager.cs
@@ -64,6 +64,11 @@ namespace MediaBrowser.Common.Kernel
/// The _logger
/// </summary>
private readonly ILogger _logger;
+
+ /// <summary>
+ /// The _application host
+ /// </summary>
+ private readonly IApplicationHost _applicationHost;
/// <summary>
/// The _supports native web socket
@@ -108,12 +113,14 @@ namespace MediaBrowser.Common.Kernel
/// <summary>
/// Initializes a new instance of the <see cref="TcpManager" /> class.
/// </summary>
+ /// <param name="applicationHost">The application host.</param>
/// <param name="kernel">The kernel.</param>
/// <param name="logger">The logger.</param>
- public TcpManager(IKernel kernel, ILogger logger)
+ public TcpManager(IApplicationHost applicationHost, IKernel kernel, ILogger logger)
: base(kernel)
{
_logger = logger;
+ _applicationHost = applicationHost;
if (kernel.IsFirstRun)
{
@@ -182,7 +189,7 @@ namespace MediaBrowser.Common.Kernel
try
{
- HttpServer = new HttpServer(Kernel.HttpServerUrlPrefix, "Media Browser", Kernel, _logger);
+ HttpServer = new HttpServer(Kernel.HttpServerUrlPrefix, "Media Browser", _applicationHost, Kernel, _logger);
}
catch (HttpListenerException ex)
{
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj
index b806df856..c7b162dee 100644
--- a/MediaBrowser.Common/MediaBrowser.Common.csproj
+++ b/MediaBrowser.Common/MediaBrowser.Common.csproj
@@ -34,7 +34,8 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
- <ApplicationIcon>Resources\Images\Icon.ico</ApplicationIcon>
+ <ApplicationIcon>
+ </ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="Alchemy">
@@ -94,7 +95,6 @@
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
- <Reference Include="System.Deployment" />
<Reference Include="System.Management" />
<Reference Include="System.Net" />
<Reference Include="System.Net.Http" />
@@ -118,13 +118,8 @@
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
- <Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
- <Compile Include="Api\Logging\LogFileWebSocketListener.cs" />
- <Compile Include="Api\ScheduledTasks\ScheduledTaskService.cs" />
- <Compile Include="Api\ScheduledTasks\ScheduledTasksWebSocketListener.cs" />
- <Compile Include="Api\SystemInfoWebSocketListener.cs" />
<Compile Include="Events\EventHelper.cs" />
<Compile Include="Extensions\BaseExtensions.cs" />
<Compile Include="Events\GenericEventArgs.cs" />
@@ -156,8 +151,6 @@
<Compile Include="Net\MimeTypes.cs" />
<Compile Include="Net\NativeWebSocket.cs" />
<Compile Include="Net\NetUtils.cs" />
- <Compile Include="Net\NetworkShares.cs" />
- <Compile Include="Net\StaticResult.cs" />
<Compile Include="Net\UdpServer.cs" />
<Compile Include="Net\WebSocketConnection.cs" />
<Compile Include="Plugins\BaseUiPlugin.cs" />
@@ -193,9 +186,6 @@
<Compile Include="ScheduledTasks\IntervalTrigger.cs" />
<Compile Include="ScheduledTasks\IScheduledTask.cs" />
<Compile Include="ScheduledTasks\WeeklyTrigger.cs" />
- <Compile Include="Updates\ApplicationUpdateCheck.cs" />
- <Compile Include="Updates\ApplicationUpdater.cs" />
- <Compile Include="Updates\ClickOnceHelper.cs" />
<Compile Include="Win32\NativeMethods.cs" />
</ItemGroup>
<ItemGroup>
@@ -217,9 +207,6 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
- <Resource Include="Resources\Images\Icon.ico" />
- </ItemGroup>
- <ItemGroup>
<Resource Include="README.txt" />
<Content Include="swagger-ui\css\screen.css" />
<Resource Include="swagger-ui\images\pet_store_api.png" />
diff --git a/MediaBrowser.Common/Net/HttpServer.cs b/MediaBrowser.Common/Net/HttpServer.cs
index 184b82c16..b09c95da0 100644
--- a/MediaBrowser.Common/Net/HttpServer.cs
+++ b/MediaBrowser.Common/Net/HttpServer.cs
@@ -46,6 +46,12 @@ namespace MediaBrowser.Common.Net
private IKernel Kernel { get; set; }
/// <summary>
+ /// Gets or sets the application host.
+ /// </summary>
+ /// <value>The application host.</value>
+ private IApplicationHost ApplicationHost { get; set; }
+
+ /// <summary>
/// This subscribes to HttpListener requests and finds the appropriate BaseHandler to process it
/// </summary>
/// <value>The HTTP listener.</value>
@@ -67,11 +73,12 @@ namespace MediaBrowser.Common.Net
/// </summary>
/// <param name="urlPrefix">The URL.</param>
/// <param name="serverName">Name of the product.</param>
+ /// <param name="applicationHost">The application host.</param>
/// <param name="kernel">The kernel.</param>
/// <param name="logger">The logger.</param>
/// <param name="defaultRedirectpath">The default redirectpath.</param>
/// <exception cref="System.ArgumentNullException">urlPrefix</exception>
- public HttpServer(string urlPrefix, string serverName, IKernel kernel, ILogger logger, string defaultRedirectpath = null)
+ public HttpServer(string urlPrefix, string serverName, IApplicationHost applicationHost, IKernel kernel, ILogger logger, string defaultRedirectpath = null)
: base()
{
if (string.IsNullOrEmpty(urlPrefix))
@@ -86,9 +93,14 @@ namespace MediaBrowser.Common.Net
{
throw new ArgumentNullException("logger");
}
+ if (applicationHost == null)
+ {
+ throw new ArgumentNullException("applicationHost");
+ }
DefaultRedirectPath = defaultRedirectpath;
_logger = logger;
+ ApplicationHost = applicationHost;
EndpointHostConfig.Instance.ServiceStackHandlerFactoryPath = null;
EndpointHostConfig.Instance.MetadataRedirectPath = "metadata";
@@ -144,6 +156,7 @@ namespace MediaBrowser.Common.Net
container.Register(Kernel);
container.Register(_logger);
+ container.Register(ApplicationHost);
foreach (var service in Kernel.RestServices)
{
diff --git a/MediaBrowser.Common/Net/NetworkShares.cs b/MediaBrowser.Common/Net/NetworkShares.cs
deleted file mode 100644
index 202865b4c..000000000
--- a/MediaBrowser.Common/Net/NetworkShares.cs
+++ /dev/null
@@ -1,644 +0,0 @@
-using System;
-using System.IO;
-using System.Collections;
-using System.Runtime.InteropServices;
-
-namespace MediaBrowser.Common.Net
-{
- /// <summary>
- /// Type of share
- /// </summary>
- [Flags]
- public enum ShareType
- {
- /// <summary>Disk share</summary>
- Disk = 0,
- /// <summary>Printer share</summary>
- Printer = 1,
- /// <summary>Device share</summary>
- Device = 2,
- /// <summary>IPC share</summary>
- IPC = 3,
- /// <summary>Special share</summary>
- Special = -2147483648, // 0x80000000,
- }
-
- #region Share
-
- /// <summary>
- /// Information about a local share
- /// </summary>
- public class Share
- {
- #region Private data
-
- private string _server;
- private string _netName;
- private string _path;
- private ShareType _shareType;
- private string _remark;
-
- #endregion
-
- #region Constructor
-
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="Server"></param>
- /// <param name="shi"></param>
- public Share(string server, string netName, string path, ShareType shareType, string remark)
- {
- if (ShareType.Special == shareType && "IPC$" == netName)
- {
- shareType |= ShareType.IPC;
- }
-
- _server = server;
- _netName = netName;
- _path = path;
- _shareType = shareType;
- _remark = remark;
- }
-
- #endregion
-
- #region Properties
-
- /// <summary>
- /// The name of the computer that this share belongs to
- /// </summary>
- public string Server
- {
- get { return _server; }
- }
-
- /// <summary>
- /// Share name
- /// </summary>
- public string NetName
- {
- get { return _netName; }
- }
-
- /// <summary>
- /// Local path
- /// </summary>
- public string Path
- {
- get { return _path; }
- }
-
- /// <summary>
- /// Share type
- /// </summary>
- public ShareType ShareType
- {
- get { return _shareType; }
- }
-
- /// <summary>
- /// Comment
- /// </summary>
- public string Remark
- {
- get { return _remark; }
- }
-
- /// <summary>
- /// Returns true if this is a file system share
- /// </summary>
- public bool IsFileSystem
- {
- get
- {
- // Shared device
- if (0 != (_shareType & ShareType.Device)) return false;
- // IPC share
- if (0 != (_shareType & ShareType.IPC)) return false;
- // Shared printer
- if (0 != (_shareType & ShareType.Printer)) return false;
-
- // Standard disk share
- if (0 == (_shareType & ShareType.Special)) return true;
-
- // Special disk share (e.g. C$)
- if (ShareType.Special == _shareType && null != _netName && 0 != _netName.Length)
- return true;
- else
- return false;
- }
- }
-
- /// <summary>
- /// Get the root of a disk-based share
- /// </summary>
- public DirectoryInfo Root
- {
- get
- {
- if (IsFileSystem)
- {
- if (null == _server || 0 == _server.Length)
- if (null == _path || 0 == _path.Length)
- return new DirectoryInfo(ToString());
- else
- return new DirectoryInfo(_path);
- else
- return new DirectoryInfo(ToString());
- }
- else
- return null;
- }
- }
-
- #endregion
-
- /// <summary>
- /// Returns the path to this share
- /// </summary>
- /// <returns></returns>
- public override string ToString()
- {
- if (null == _server || 0 == _server.Length)
- {
- return string.Format(@"\\{0}\{1}", Environment.MachineName, _netName);
- }
- else
- return string.Format(@"\\{0}\{1}", _server, _netName);
- }
-
- /// <summary>
- /// Returns true if this share matches the local path
- /// </summary>
- /// <param name="path"></param>
- /// <returns></returns>
- public bool MatchesPath(string path)
- {
- if (!IsFileSystem) return false;
- if (null == path || 0 == path.Length) return true;
-
- return path.ToLower().StartsWith(_path.ToLower());
- }
- }
-
- #endregion
-
- /// <summary>
- /// A collection of shares
- /// </summary>
- public class ShareCollection : ReadOnlyCollectionBase
- {
- #region Platform
-
- /// <summary>
- /// Is this an NT platform?
- /// </summary>
- protected static bool IsNT
- {
- get { return (PlatformID.Win32NT == Environment.OSVersion.Platform); }
- }
-
- /// <summary>
- /// Returns true if this is Windows 2000 or higher
- /// </summary>
- protected static bool IsW2KUp
- {
- get
- {
- OperatingSystem os = Environment.OSVersion;
- if (PlatformID.Win32NT == os.Platform && os.Version.Major >= 5)
- return true;
- else
- return false;
- }
- }
-
- #endregion
-
- #region Interop
-
- #region Constants
-
- /// <summary>Maximum path length</summary>
- protected const int MAX_PATH = 260;
- /// <summary>No error</summary>
- protected const int NO_ERROR = 0;
- /// <summary>Access denied</summary>
- protected const int ERROR_ACCESS_DENIED = 5;
- /// <summary>Access denied</summary>
- protected const int ERROR_WRONG_LEVEL = 124;
- /// <summary>More data available</summary>
- protected const int ERROR_MORE_DATA = 234;
- /// <summary>Not connected</summary>
- protected const int ERROR_NOT_CONNECTED = 2250;
- /// <summary>Level 1</summary>
- protected const int UNIVERSAL_NAME_INFO_LEVEL = 1;
- /// <summary>Max extries (9x)</summary>
- protected const int MAX_SI50_ENTRIES = 20;
-
- #endregion
-
- #region Structures
-
- /// <summary>Unc name</summary>
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
- protected struct UNIVERSAL_NAME_INFO
- {
- [MarshalAs(UnmanagedType.LPTStr)]
- public string lpUniversalName;
- }
-
- /// <summary>Share information, NT, level 2</summary>
- /// <remarks>
- /// Requires admin rights to work.
- /// </remarks>
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- protected struct SHARE_INFO_2
- {
- [MarshalAs(UnmanagedType.LPWStr)]
- public string NetName;
- public ShareType ShareType;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string Remark;
- public int Permissions;
- public int MaxUsers;
- public int CurrentUsers;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string Path;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string Password;
- }
-
- /// <summary>Share information, NT, level 1</summary>
- /// <remarks>
- /// Fallback when no admin rights.
- /// </remarks>
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
- protected struct SHARE_INFO_1
- {
- [MarshalAs(UnmanagedType.LPWStr)]
- public string NetName;
- public ShareType ShareType;
- [MarshalAs(UnmanagedType.LPWStr)]
- public string Remark;
- }
-
- /// <summary>Share information, Win9x</summary>
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
- protected struct SHARE_INFO_50
- {
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 13)]
- public string NetName;
-
- public byte bShareType;
- public ushort Flags;
-
- [MarshalAs(UnmanagedType.LPTStr)]
- public string Remark;
- [MarshalAs(UnmanagedType.LPTStr)]
- public string Path;
-
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]
- public string PasswordRW;
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]
- public string PasswordRO;
-
- public ShareType ShareType
- {
- get { return (ShareType)((int)bShareType & 0x7F); }
- }
- }
-
- /// <summary>Share information level 1, Win9x</summary>
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
- protected struct SHARE_INFO_1_9x
- {
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 13)]
- public string NetName;
- public byte Padding;
-
- public ushort bShareType;
-
- [MarshalAs(UnmanagedType.LPTStr)]
- public string Remark;
-
- public ShareType ShareType
- {
- get { return (ShareType)((int)bShareType & 0x7FFF); }
- }
- }
-
- #endregion
-
- #region Functions
-
- /// <summary>Get a UNC name</summary>
- [DllImport("mpr", CharSet = CharSet.Auto)]
- protected static extern int WNetGetUniversalName(string lpLocalPath,
- int dwInfoLevel, ref UNIVERSAL_NAME_INFO lpBuffer, ref int lpBufferSize);
-
- /// <summary>Get a UNC name</summary>
- [DllImport("mpr", CharSet = CharSet.Auto)]
- protected static extern int WNetGetUniversalName(string lpLocalPath,
- int dwInfoLevel, IntPtr lpBuffer, ref int lpBufferSize);
-
- /// <summary>Enumerate shares (NT)</summary>
- [DllImport("netapi32", CharSet = CharSet.Unicode)]
- protected static extern int NetShareEnum(string lpServerName, int dwLevel,
- out IntPtr lpBuffer, int dwPrefMaxLen, out int entriesRead,
- out int totalEntries, ref int hResume);
-
- /// <summary>Enumerate shares (9x)</summary>
- [DllImport("svrapi", CharSet = CharSet.Ansi)]
- protected static extern int NetShareEnum(
- [MarshalAs(UnmanagedType.LPTStr)] string lpServerName, int dwLevel,
- IntPtr lpBuffer, ushort cbBuffer, out ushort entriesRead,
- out ushort totalEntries);
-
- /// <summary>Free the buffer (NT)</summary>
- [DllImport("netapi32")]
- protected static extern int NetApiBufferFree(IntPtr lpBuffer);
-
- #endregion
-
- #region Enumerate shares
-
- /// <summary>
- /// Enumerates the shares on Windows NT
- /// </summary>
- /// <param name="server">The server name</param>
- /// <param name="shares">The ShareCollection</param>
- protected static void EnumerateSharesNT(string server, ShareCollection shares)
- {
- int level = 2;
- int entriesRead, totalEntries, nRet, hResume = 0;
- IntPtr pBuffer = IntPtr.Zero;
-
- try
- {
- nRet = NetShareEnum(server, level, out pBuffer, -1,
- out entriesRead, out totalEntries, ref hResume);
-
- if (ERROR_ACCESS_DENIED == nRet)
- {
- //Need admin for level 2, drop to level 1
- level = 1;
- nRet = NetShareEnum(server, level, out pBuffer, -1,
- out entriesRead, out totalEntries, ref hResume);
- }
-
- if (NO_ERROR == nRet && entriesRead > 0)
- {
- Type t = (2 == level) ? typeof(SHARE_INFO_2) : typeof(SHARE_INFO_1);
- int offset = Marshal.SizeOf(t);
-
- for (int i = 0, lpItem = pBuffer.ToInt32(); i < entriesRead; i++, lpItem += offset)
- {
- IntPtr pItem = new IntPtr(lpItem);
- if (1 == level)
- {
- SHARE_INFO_1 si = (SHARE_INFO_1)Marshal.PtrToStructure(pItem, t);
- shares.Add(si.NetName, string.Empty, si.ShareType, si.Remark);
- }
- else
- {
- SHARE_INFO_2 si = (SHARE_INFO_2)Marshal.PtrToStructure(pItem, t);
- shares.Add(si.NetName, si.Path, si.ShareType, si.Remark);
- }
- }
- }
-
- }
- finally
- {
- // Clean up buffer allocated by system
- if (IntPtr.Zero != pBuffer)
- NetApiBufferFree(pBuffer);
- }
- }
-
- /// <summary>
- /// Enumerates the shares on Windows 9x
- /// </summary>
- /// <param name="server">The server name</param>
- /// <param name="shares">The ShareCollection</param>
- protected static void EnumerateShares9x(string server, ShareCollection shares)
- {
- int level = 50;
- int nRet = 0;
- ushort entriesRead, totalEntries;
-
- Type t = typeof(SHARE_INFO_50);
- int size = Marshal.SizeOf(t);
- ushort cbBuffer = (ushort)(MAX_SI50_ENTRIES * size);
- //On Win9x, must allocate buffer before calling API
- IntPtr pBuffer = Marshal.AllocHGlobal(cbBuffer);
-
- try
- {
- nRet = NetShareEnum(server, level, pBuffer, cbBuffer,
- out entriesRead, out totalEntries);
-
- if (ERROR_WRONG_LEVEL == nRet)
- {
- level = 1;
- t = typeof(SHARE_INFO_1_9x);
- size = Marshal.SizeOf(t);
-
- nRet = NetShareEnum(server, level, pBuffer, cbBuffer,
- out entriesRead, out totalEntries);
- }
-
- if (NO_ERROR == nRet || ERROR_MORE_DATA == nRet)
- {
- for (int i = 0, lpItem = pBuffer.ToInt32(); i < entriesRead; i++, lpItem += size)
- {
- IntPtr pItem = new IntPtr(lpItem);
-
- if (1 == level)
- {
- SHARE_INFO_1_9x si = (SHARE_INFO_1_9x)Marshal.PtrToStructure(pItem, t);
- shares.Add(si.NetName, string.Empty, si.ShareType, si.Remark);
- }
- else
- {
- SHARE_INFO_50 si = (SHARE_INFO_50)Marshal.PtrToStructure(pItem, t);
- shares.Add(si.NetName, si.Path, si.ShareType, si.Remark);
- }
- }
- }
- else
- Console.WriteLine(nRet);
-
- }
- finally
- {
- //Clean up buffer
- Marshal.FreeHGlobal(pBuffer);
- }
- }
-
- /// <summary>
- /// Enumerates the shares
- /// </summary>
- /// <param name="server">The server name</param>
- /// <param name="shares">The ShareCollection</param>
- protected static void EnumerateShares(string server, ShareCollection shares)
- {
- if (null != server && 0 != server.Length && !IsW2KUp)
- {
- server = server.ToUpper();
-
- // On NT4, 9x and Me, server has to start with "\\"
- if (!('\\' == server[0] && '\\' == server[1]))
- server = @"\\" + server;
- }
-
- if (IsNT)
- EnumerateSharesNT(server, shares);
- else
- EnumerateShares9x(server, shares);
- }
-
- #endregion
-
- #endregion
-
- #region Static methods
-
- /// <summary>
- /// Returns true if fileName is a valid local file-name of the form:
- /// X:\, where X is a drive letter from A-Z
- /// </summary>
- /// <param name="fileName">The filename to check</param>
- /// <returns></returns>
- public static bool IsValidFilePath(string fileName)
- {
- if (null == fileName || 0 == fileName.Length) return false;
-
- char drive = char.ToUpper(fileName[0]);
- if ('A' > drive || drive > 'Z')
- return false;
-
- else if (Path.VolumeSeparatorChar != fileName[1])
- return false;
- else if (Path.DirectorySeparatorChar != fileName[2])
- return false;
- else
- return true;
- }
-
- #endregion
-
- /// <summary>The name of the server this collection represents</summary>
- private string _server;
-
- #region Constructor
-
- /// <summary>
- /// Default constructor - local machine
- /// </summary>
- public ShareCollection()
- {
- _server = string.Empty;
- EnumerateShares(_server, this);
- }
-
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="Server"></param>
- public ShareCollection(string server)
- {
- _server = server;
- EnumerateShares(_server, this);
- }
-
- #endregion
-
- #region Add
-
- protected void Add(Share share)
- {
- InnerList.Add(share);
- }
-
- protected void Add(string netName, string path, ShareType shareType, string remark)
- {
- InnerList.Add(new Share(_server, netName, path, shareType, remark));
- }
-
- #endregion
-
- #region Properties
-
- /// <summary>
- /// Returns the name of the server this collection represents
- /// </summary>
- public string Server
- {
- get { return _server; }
- }
-
- /// <summary>
- /// Returns the <see cref="Share"/> at the specified index.
- /// </summary>
- public Share this[int index]
- {
- get { return (Share)InnerList[index]; }
- }
-
- /// <summary>
- /// Returns the <see cref="Share"/> which matches a given local path
- /// </summary>
- /// <param name="path">The path to match</param>
- public Share this[string path]
- {
- get
- {
- if (null == path || 0 == path.Length) return null;
-
- path = Path.GetFullPath(path);
- if (!IsValidFilePath(path)) return null;
-
- Share match = null;
-
- for (int i = 0; i < InnerList.Count; i++)
- {
- Share s = (Share)InnerList[i];
-
- if (s.IsFileSystem && s.MatchesPath(path))
- {
- //Store first match
- if (null == match)
- match = s;
-
- // If this has a longer path,
- // and this is a disk share or match is a special share,
- // then this is a better match
- else if (match.Path.Length < s.Path.Length)
- {
- if (ShareType.Disk == s.ShareType || ShareType.Disk != match.ShareType)
- match = s;
- }
- }
- }
-
- return match;
- }
- }
-
- #endregion
-
- /// <summary>
- /// Copy this collection to an array
- /// </summary>
- /// <param name="array"></param>
- /// <param name="index"></param>
- public void CopyTo(Share[] array, int index)
- {
- InnerList.CopyTo(array, index);
- }
- }
-} \ No newline at end of file
diff --git a/MediaBrowser.Common/Net/StaticResult.cs b/MediaBrowser.Common/Net/StaticResult.cs
deleted file mode 100644
index 0dd6372cf..000000000
--- a/MediaBrowser.Common/Net/StaticResult.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Common.Net
-{
- public class StaticResult
- {
- public Stream Stream { get; set; }
- }
-}
diff --git a/MediaBrowser.Common/Resources/Images/Icon.ico b/MediaBrowser.Common/Resources/Images/Icon.ico
deleted file mode 100644
index bea939de4..000000000
--- a/MediaBrowser.Common/Resources/Images/Icon.ico
+++ /dev/null
Binary files differ
diff --git a/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs b/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs
index 99dd7ab01..395c73a84 100644
--- a/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs
+++ b/MediaBrowser.Common/ScheduledTasks/BaseScheduledTask.cs
@@ -171,7 +171,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// Gets the current progress.
/// </summary>
/// <value>The current progress.</value>
- public TaskProgress CurrentProgress { get; private set; }
+ public double? CurrentProgress { get; private set; }
/// <summary>
/// The _triggers
@@ -246,7 +246,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param>
/// <returns>Task.</returns>
- protected abstract Task ExecuteInternal(CancellationToken cancellationToken, IProgress<TaskProgress> progress);
+ protected abstract Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress);
/// <summary>
/// Gets the name of the task
@@ -355,7 +355,7 @@ namespace MediaBrowser.Common.ScheduledTasks
Logger.Info("Executing {0}", Name);
- var progress = new Progress<TaskProgress>();
+ var progress = new Progress<double>();
progress.ProgressChanged += progress_ProgressChanged;
@@ -426,7 +426,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The e.</param>
- void progress_ProgressChanged(object sender, TaskProgress e)
+ void progress_ProgressChanged(object sender, double e)
{
CurrentProgress = e;
}
diff --git a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs
index a3809c4b9..95d1edf63 100644
--- a/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs
+++ b/MediaBrowser.Common/ScheduledTasks/IScheduledTask.cs
@@ -34,7 +34,7 @@ namespace MediaBrowser.Common.ScheduledTasks
/// Gets the current progress.
/// </summary>
/// <value>The current progress.</value>
- TaskProgress CurrentProgress { get; }
+ double? CurrentProgress { get; }
/// <summary>
/// Gets the name of the task
diff --git a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs
index 34421ca1f..95c4c6a66 100644
--- a/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs
+++ b/MediaBrowser.Common/ScheduledTasks/ScheduledTaskHelpers.cs
@@ -20,7 +20,7 @@ namespace MediaBrowser.Common.ScheduledTasks
return new TaskInfo
{
Name = task.Name,
- CurrentProgress = task.CurrentProgress,
+ CurrentProgressPercentage = task.CurrentProgress,
State = task.State,
Id = task.Id,
LastExecutionResult = task.LastExecutionResult,
diff --git a/MediaBrowser.Common/ScheduledTasks/Tasks/DeleteCacheFileTask.cs b/MediaBrowser.Common/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
index 98c6d672a..2a9bc4a0d 100644
--- a/MediaBrowser.Common/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
+++ b/MediaBrowser.Common/ScheduledTasks/Tasks/DeleteCacheFileTask.cs
@@ -33,7 +33,7 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param>
/// <returns>Task.</returns>
- protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<TaskProgress> progress)
+ protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress)
{
return Task.Run(() =>
{
@@ -51,7 +51,7 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
/// <param name="directory">The directory.</param>
/// <param name="minDateModified">The min date modified.</param>
/// <param name="progress">The progress.</param>
- private void DeleteCacheFilesFromDirectory(CancellationToken cancellationToken, string directory, DateTime minDateModified, IProgress<TaskProgress> progress)
+ private void DeleteCacheFilesFromDirectory(CancellationToken cancellationToken, string directory, DateTime minDateModified, IProgress<double> progress)
{
var filesToDelete = new DirectoryInfo(directory).EnumerateFileSystemInfos("*", SearchOption.AllDirectories)
.Where(f => !f.Attributes.HasFlag(FileAttributes.Directory) && f.LastWriteTimeUtc < minDateModified)
@@ -64,7 +64,7 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
double percent = index;
percent /= filesToDelete.Count;
- progress.Report(new TaskProgress { Description = file.FullName, PercentComplete = 100 * percent });
+ progress.Report(100 * percent);
cancellationToken.ThrowIfCancellationRequested();
@@ -73,7 +73,7 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
index++;
}
- progress.Report(new TaskProgress { PercentComplete = 100 });
+ progress.Report(100);
}
/// <summary>
diff --git a/MediaBrowser.Common/ScheduledTasks/Tasks/DeleteLogFileTask.cs b/MediaBrowser.Common/ScheduledTasks/Tasks/DeleteLogFileTask.cs
index afb21187c..a1068a263 100644
--- a/MediaBrowser.Common/ScheduledTasks/Tasks/DeleteLogFileTask.cs
+++ b/MediaBrowser.Common/ScheduledTasks/Tasks/DeleteLogFileTask.cs
@@ -33,7 +33,7 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param>
/// <returns>Task.</returns>
- protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<TaskProgress> progress)
+ protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress)
{
return Task.Run(() =>
{
@@ -51,7 +51,7 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
double percent = index;
percent /= filesToDelete.Count;
- progress.Report(new TaskProgress { Description = file.FullName, PercentComplete = 100 * percent });
+ progress.Report(100 * percent);
cancellationToken.ThrowIfCancellationRequested();
@@ -60,7 +60,7 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
index++;
}
- progress.Report(new TaskProgress { PercentComplete = 100 });
+ progress.Report(100);
});
}
diff --git a/MediaBrowser.Common/ScheduledTasks/Tasks/ReloadLoggerTask.cs b/MediaBrowser.Common/ScheduledTasks/Tasks/ReloadLoggerTask.cs
index 24aaad57f..a4f06f205 100644
--- a/MediaBrowser.Common/ScheduledTasks/Tasks/ReloadLoggerTask.cs
+++ b/MediaBrowser.Common/ScheduledTasks/Tasks/ReloadLoggerTask.cs
@@ -31,11 +31,11 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param>
/// <returns>Task.</returns>
- protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<TaskProgress> progress)
+ protected override Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress)
{
cancellationToken.ThrowIfCancellationRequested();
- progress.Report(new TaskProgress { PercentComplete = 0 });
+ progress.Report(0);
return Task.Run(() => Kernel.ReloadLogger());
}
diff --git a/MediaBrowser.Common/ScheduledTasks/Tasks/SystemUpdateTask.cs b/MediaBrowser.Common/ScheduledTasks/Tasks/SystemUpdateTask.cs
index a7e3f90a0..f9950424f 100644
--- a/MediaBrowser.Common/ScheduledTasks/Tasks/SystemUpdateTask.cs
+++ b/MediaBrowser.Common/ScheduledTasks/Tasks/SystemUpdateTask.cs
@@ -1,10 +1,7 @@
using MediaBrowser.Common.Kernel;
-using MediaBrowser.Common.Updates;
-using MediaBrowser.Model.Tasks;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
-using System.Deployment.Application;
using System.Threading;
using System.Threading.Tasks;
@@ -17,6 +14,21 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
public class SystemUpdateTask : BaseScheduledTask<IKernel>
{
/// <summary>
+ /// The _app host
+ /// </summary>
+ private readonly IApplicationHost _appHost;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SystemUpdateTask" /> class.
+ /// </summary>
+ /// <param name="appHost">The app host.</param>
+ [ImportingConstructor]
+ public SystemUpdateTask([Import("appHost")] IApplicationHost appHost)
+ {
+ _appHost = appHost;
+ }
+
+ /// <summary>
/// Creates the triggers that define when the task will run
/// </summary>
/// <returns>IEnumerable{BaseTaskTrigger}.</returns>
@@ -37,26 +49,26 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
/// <param name="cancellationToken">The cancellation token.</param>
/// <param name="progress">The progress.</param>
/// <returns>Task.</returns>
- protected override async Task ExecuteInternal(CancellationToken cancellationToken, IProgress<TaskProgress> progress)
+ protected override async Task ExecuteInternal(CancellationToken cancellationToken, IProgress<double> progress)
{
- if (!ApplicationDeployment.IsNetworkDeployed) return;
+ if (!_appHost.CanSelfUpdate) return;
- EventHandler<TaskProgress> innerProgressHandler = (sender, e) => progress.Report(new TaskProgress { PercentComplete = e.PercentComplete * .1 });
+ EventHandler<double> innerProgressHandler = (sender, e) => progress.Report(e * .1);
// Create a progress object for the update check
- var innerProgress = new Progress<TaskProgress>();
+ var innerProgress = new Progress<double>();
innerProgress.ProgressChanged += innerProgressHandler;
- var updateInfo = await new ApplicationUpdateCheck().CheckForApplicationUpdate(cancellationToken, innerProgress).ConfigureAwait(false);
+ var updateInfo = await _appHost.CheckForApplicationUpdate(cancellationToken, innerProgress).ConfigureAwait(false);
// Release the event handler
innerProgress.ProgressChanged -= innerProgressHandler;
- progress.Report(new TaskProgress { PercentComplete = 10 });
+ progress.Report(10);
- if (!updateInfo.UpdateAvailable)
+ if (!updateInfo.IsUpdateAvailable)
{
- progress.Report(new TaskProgress { PercentComplete = 100 });
+ progress.Report(100);
return;
}
@@ -66,12 +78,12 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
{
Logger.Info("Update Revision {0} available. Updating...", updateInfo.AvailableVersion);
- innerProgressHandler = (sender, e) => progress.Report(new TaskProgress { PercentComplete = (e.PercentComplete * .9) + .1 });
+ innerProgressHandler = (sender, e) => progress.Report((e * .9) + .1);
- innerProgress = new Progress<TaskProgress>();
+ innerProgress = new Progress<double>();
innerProgress.ProgressChanged += innerProgressHandler;
- await new ApplicationUpdater().UpdateApplication(cancellationToken, innerProgress).ConfigureAwait(false);
+ await _appHost.UpdateApplication(cancellationToken, innerProgress).ConfigureAwait(false);
// Release the event handler
innerProgress.ProgressChanged -= innerProgressHandler;
@@ -83,7 +95,7 @@ namespace MediaBrowser.Common.ScheduledTasks.Tasks
Logger.Info("A new version of Media Browser is available.");
}
- progress.Report(new TaskProgress { PercentComplete = 100 });
+ progress.Report(100);
}
/// <summary>
diff --git a/MediaBrowser.Common/Updates/ApplicationUpdateCheck.cs b/MediaBrowser.Common/Updates/ApplicationUpdateCheck.cs
deleted file mode 100644
index 7501d7321..000000000
--- a/MediaBrowser.Common/Updates/ApplicationUpdateCheck.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-using MediaBrowser.Model.Tasks;
-using System;
-using System.Deployment.Application;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Common.Updates
-{
- /// <summary>
- /// Class ApplicationUpdateCheck
- /// </summary>
- public class ApplicationUpdateCheck
- {
- /// <summary>
- /// The _task completion source
- /// </summary>
- private TaskCompletionSource<CheckForUpdateCompletedEventArgs> _taskCompletionSource;
-
- /// <summary>
- /// The _progress
- /// </summary>
- private IProgress<TaskProgress> _progress;
-
- /// <summary>
- /// Checks for application update.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task{CheckForUpdateCompletedEventArgs}.</returns>
- /// <exception cref="System.InvalidOperationException">Current deployment is not a ClickOnce deployment</exception>
- public Task<CheckForUpdateCompletedEventArgs> CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress<TaskProgress> progress)
- {
- if (!ApplicationDeployment.IsNetworkDeployed)
- {
- throw new InvalidOperationException("Current deployment is not network deployed.");
- }
-
- _progress = progress;
-
- _taskCompletionSource = new TaskCompletionSource<CheckForUpdateCompletedEventArgs>();
-
- var deployment = ApplicationDeployment.CurrentDeployment;
-
- cancellationToken.Register(deployment.CheckForUpdateAsyncCancel);
-
- cancellationToken.ThrowIfCancellationRequested();
-
- deployment.CheckForUpdateCompleted += deployment_CheckForUpdateCompleted;
- deployment.CheckForUpdateProgressChanged += deployment_CheckForUpdateProgressChanged;
-
- deployment.CheckForUpdateAsync();
-
- return _taskCompletionSource.Task;
- }
-
- /// <summary>
- /// Handles the CheckForUpdateCompleted event of the deployment control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="CheckForUpdateCompletedEventArgs" /> instance containing the event data.</param>
- void deployment_CheckForUpdateCompleted(object sender, CheckForUpdateCompletedEventArgs e)
- {
- var deployment = ApplicationDeployment.CurrentDeployment;
-
- deployment.CheckForUpdateCompleted -= deployment_CheckForUpdateCompleted;
- deployment.CheckForUpdateProgressChanged -= deployment_CheckForUpdateProgressChanged;
-
- if (e.Error != null)
- {
- _taskCompletionSource.SetException(e.Error);
- }
- else if (e.Cancelled)
- {
- _taskCompletionSource.SetCanceled();
- }
- else
- {
- _taskCompletionSource.SetResult(e);
- }
- }
-
- /// <summary>
- /// Handles the CheckForUpdateProgressChanged event of the deployment control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="DeploymentProgressChangedEventArgs" /> instance containing the event data.</param>
- void deployment_CheckForUpdateProgressChanged(object sender, DeploymentProgressChangedEventArgs e)
- {
- _progress.Report(new TaskProgress { PercentComplete = e.ProgressPercentage });
- }
- }
-}
diff --git a/MediaBrowser.Common/Updates/ApplicationUpdater.cs b/MediaBrowser.Common/Updates/ApplicationUpdater.cs
deleted file mode 100644
index d8ae87b37..000000000
--- a/MediaBrowser.Common/Updates/ApplicationUpdater.cs
+++ /dev/null
@@ -1,93 +0,0 @@
-using MediaBrowser.Model.Tasks;
-using System;
-using System.ComponentModel;
-using System.Deployment.Application;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Common.Updates
-{
- /// <summary>
- /// Class ApplicationUpdater
- /// </summary>
- public class ApplicationUpdater
- {
- /// <summary>
- /// The _task completion source
- /// </summary>
- private TaskCompletionSource<AsyncCompletedEventArgs> _taskCompletionSource;
-
- /// <summary>
- /// The _progress
- /// </summary>
- private IProgress<TaskProgress> _progress;
-
- /// <summary>
- /// Updates the application
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task{AsyncCompletedEventArgs}.</returns>
- /// <exception cref="System.InvalidOperationException">Current deployment is not network deployed.</exception>
- public Task<AsyncCompletedEventArgs> UpdateApplication(CancellationToken cancellationToken, IProgress<TaskProgress> progress)
- {
- if (!ApplicationDeployment.IsNetworkDeployed)
- {
- throw new InvalidOperationException("Current deployment is not network deployed.");
- }
-
- _progress = progress;
-
- _taskCompletionSource = new TaskCompletionSource<AsyncCompletedEventArgs>();
-
- var deployment = ApplicationDeployment.CurrentDeployment;
-
- cancellationToken.Register(deployment.UpdateAsyncCancel);
-
- cancellationToken.ThrowIfCancellationRequested();
-
- deployment.UpdateCompleted += deployment_UpdateCompleted;
- deployment.UpdateProgressChanged += deployment_UpdateProgressChanged;
-
- deployment.UpdateAsync();
-
- return _taskCompletionSource.Task;
- }
-
- /// <summary>
- /// Handles the UpdateCompleted event of the deployment control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="AsyncCompletedEventArgs" /> instance containing the event data.</param>
- void deployment_UpdateCompleted(object sender, AsyncCompletedEventArgs e)
- {
- var deployment = ApplicationDeployment.CurrentDeployment;
-
- deployment.UpdateCompleted -= deployment_UpdateCompleted;
- deployment.UpdateProgressChanged -= deployment_UpdateProgressChanged;
-
- if (e.Error != null)
- {
- _taskCompletionSource.SetException(e.Error);
- }
- else if (e.Cancelled)
- {
- _taskCompletionSource.SetCanceled();
- }
- else
- {
- _taskCompletionSource.SetResult(e);
- }
- }
-
- /// <summary>
- /// Handles the UpdateProgressChanged event of the deployment control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="DeploymentProgressChangedEventArgs" /> instance containing the event data.</param>
- void deployment_UpdateProgressChanged(object sender, DeploymentProgressChangedEventArgs e)
- {
- _progress.Report(new TaskProgress { PercentComplete = e.ProgressPercentage });
- }
- }
-}
diff --git a/MediaBrowser.Common/Updates/ClickOnceHelper.cs b/MediaBrowser.Common/Updates/ClickOnceHelper.cs
deleted file mode 100644
index 7dd0cf9c5..000000000
--- a/MediaBrowser.Common/Updates/ClickOnceHelper.cs
+++ /dev/null
@@ -1,217 +0,0 @@
-using Microsoft.Win32;
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Security.AccessControl;
-
-namespace MediaBrowser.Common.Updates
-{
- /// <summary>
- /// Class ClickOnceHelper
- /// </summary>
- public class ClickOnceHelper
- {
- /// <summary>
- /// The uninstall string
- /// </summary>
- private const string UninstallString = "UninstallString";
- /// <summary>
- /// The display name key
- /// </summary>
- private const string DisplayNameKey = "DisplayName";
- /// <summary>
- /// The uninstall string file
- /// </summary>
- private const string UninstallStringFile = "UninstallString.bat";
- /// <summary>
- /// The appref extension
- /// </summary>
- private const string ApprefExtension = ".appref-ms";
- /// <summary>
- /// The uninstall registry key
- /// </summary>
- private readonly RegistryKey UninstallRegistryKey;
-
- /// <summary>
- /// Gets the location.
- /// </summary>
- /// <value>The location.</value>
- private static string Location
- {
- get { return Assembly.GetExecutingAssembly().Location; }
- }
-
- /// <summary>
- /// Gets the name of the publisher.
- /// </summary>
- /// <value>The name of the publisher.</value>
- public string PublisherName { get; private set; }
- /// <summary>
- /// Gets the name of the product.
- /// </summary>
- /// <value>The name of the product.</value>
- public string ProductName { get; private set; }
- /// <summary>
- /// Gets the uninstall file.
- /// </summary>
- /// <value>The uninstall file.</value>
- public string UninstallFile { get; private set; }
- /// <summary>
- /// Gets the name of the suite.
- /// </summary>
- /// <value>The name of the suite.</value>
- public string SuiteName { get; private set; }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="ClickOnceHelper" /> class.
- /// </summary>
- /// <param name="publisherName">Name of the publisher.</param>
- /// <param name="productName">Name of the product.</param>
- /// <param name="suiteName">Name of the suite.</param>
- public ClickOnceHelper(string publisherName, string productName, string suiteName)
- {
- PublisherName = publisherName;
- ProductName = productName;
- SuiteName = suiteName;
-
- var publisherFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), PublisherName);
-
- if (!Directory.Exists(publisherFolder))
- {
- Directory.CreateDirectory(publisherFolder);
- }
-
- UninstallFile = Path.Combine(publisherFolder, UninstallStringFile);
-
- UninstallRegistryKey = GetUninstallRegistryKeyByProductName(ProductName);
- }
-
- /// <summary>
- /// Gets the shortcut path.
- /// </summary>
- /// <returns>System.String.</returns>
- private string GetShortcutPath()
- {
- var allProgramsPath = Environment.GetFolderPath(Environment.SpecialFolder.Programs);
-
- var shortcutPath = Path.Combine(allProgramsPath, PublisherName);
-
- if (!string.IsNullOrEmpty(SuiteName))
- {
- shortcutPath = Path.Combine(shortcutPath, SuiteName);
- }
-
- return Path.Combine(shortcutPath, ProductName) + ApprefExtension;
- }
-
- /// <summary>
- /// Gets the startup shortcut path.
- /// </summary>
- /// <returns>System.String.</returns>
- private string GetStartupShortcutPath()
- {
- var startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
-
- return Path.Combine(startupPath, ProductName) + ApprefExtension;
- }
-
- /// <summary>
- /// Adds the shortcut to startup.
- /// </summary>
- public void AddShortcutToStartup()
- {
- var startupPath = GetStartupShortcutPath();
-
- if (!File.Exists(startupPath))
- {
- File.Copy(GetShortcutPath(), startupPath);
- }
- }
-
- /// <summary>
- /// Removes the shortcut from startup.
- /// </summary>
- public void RemoveShortcutFromStartup()
- {
- var startupPath = GetStartupShortcutPath();
-
- if (File.Exists(startupPath))
- {
- File.Delete(startupPath);
- }
- }
-
- /// <summary>
- /// Updates the uninstall parameters.
- /// </summary>
- /// <param name="uninstallerFileName">Name of the uninstaller file.</param>
- public void UpdateUninstallParameters(string uninstallerFileName)
- {
- if (UninstallRegistryKey != null)
- {
- UpdateUninstallString(uninstallerFileName);
- }
- }
-
- /// <summary>
- /// Gets the name of the uninstall registry key by product.
- /// </summary>
- /// <param name="productName">Name of the product.</param>
- /// <returns>RegistryKey.</returns>
- private RegistryKey GetUninstallRegistryKeyByProductName(string productName)
- {
- var subKey = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall");
-
- if (subKey == null)
- {
- return null;
- }
-
- return subKey.GetSubKeyNames()
- .Select(name => subKey.OpenSubKey(name, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.QueryValues | RegistryRights.ReadKey | RegistryRights.SetValue))
- .Where(application => application != null)
- .FirstOrDefault(application => application.GetValueNames().Where(appKey => appKey.Equals(DisplayNameKey)).Any(appKey => application.GetValue(appKey).Equals(productName)));
- }
-
- /// <summary>
- /// Updates the uninstall string.
- /// </summary>
- /// <param name="uninstallerFileName">Name of the uninstaller file.</param>
- private void UpdateUninstallString(string uninstallerFileName)
- {
- var uninstallString = (string)UninstallRegistryKey.GetValue(UninstallString);
-
- if (!string.IsNullOrEmpty(UninstallFile) && uninstallString.StartsWith("rundll32.exe", StringComparison.OrdinalIgnoreCase))
- {
- File.WriteAllText(UninstallFile, uninstallString);
- }
-
- var str = String.Format("\"{0}\" uninstall", Path.Combine(Path.GetDirectoryName(Location), uninstallerFileName));
-
- UninstallRegistryKey.SetValue(UninstallString, str);
- }
-
- /// <summary>
- /// Uninstalls this instance.
- /// </summary>
- public void Uninstall()
- {
- RemoveShortcutFromStartup();
-
- var uninstallString = File.ReadAllText(UninstallFile);
-
- new Process
- {
- StartInfo =
- {
- Arguments = uninstallString.Substring(uninstallString.IndexOf(" ", StringComparison.OrdinalIgnoreCase) + 1),
- FileName = uninstallString.Substring(0, uninstallString.IndexOf(" ", StringComparison.OrdinalIgnoreCase)),
- UseShellExecute = false
- }
-
- }.Start();
- }
- }
-}