mirror of
https://github.com/JosefNemec/Playnite.git
synced 2026-01-09 06:11:22 +08:00
Online installer implementation finished
This commit is contained in:
parent
da3114590b
commit
c3dc70ac9b
@ -11,7 +11,7 @@ environment:
|
||||
LicensedDependenciesUrl:
|
||||
secure: ZTSg1DK6QAtwZoCBUDQ94cIaMCKWgSeJMI0dCpVJBPE40+UqG9MNu+UJjjGWjvVa
|
||||
PlayniteConfigUpdate: https://playnite.link/build/PlayniteProductionConfig.txt
|
||||
OnlineInstallerConfig: https://playnite.link/build/OnlineInstaller.json
|
||||
OnlineInstallerConfig: https://playnite.link/build/installer_mirrors.txt
|
||||
build_script:
|
||||
- pwsh: .\build\build.ps1 -Package -SdkNuget -LicensedDependenciesUrl $env:LicensedDependenciesUrl -PlayniteConfigUpdate $env:PlayniteConfigUpdate -OnlineInstallerConfig $env:OnlineInstallerConfig
|
||||
test: off
|
||||
|
||||
@ -95,10 +95,10 @@ if (!$SkipBuild)
|
||||
if ($OnlineInstallerConfig)
|
||||
{
|
||||
Write-OperationLog "Updating online installer config..."
|
||||
$locaConfigPath = "..\source\Tools\PlayniteInstaller\config.json"
|
||||
$locaConfigPath = "..\source\Tools\PlayniteInstaller\installer_mirrors.txt"
|
||||
if ($OnlineInstallerConfig.StartsWith("http"))
|
||||
{
|
||||
$configFile = Join-Path $env:TEMP "onlineconfig.json"
|
||||
$configFile = Join-Path $env:TEMP "installer_mirrors.txt"
|
||||
Invoke-WebRequest $OnlineInstallerConfig -OutFile $locaConfigPath
|
||||
}
|
||||
else
|
||||
@ -195,21 +195,6 @@ if ($SdkNuget)
|
||||
& .\buildSdkNuget.ps1 -SkipBuild -OutputPath $OutputDir | Out-Null
|
||||
}
|
||||
|
||||
# -------------------------------------------
|
||||
# Merge online installer
|
||||
# -------------------------------------------
|
||||
Write-OperationLog "Merging online installer..."
|
||||
$ilMerge = (Get-ChildItem "..\source\packages" -Filter "ILMerge.exe" -Recurse | Select -First 1).FullName
|
||||
$installerOutPath = Join-Path $OutputDir "PlayniteInstaller.exe"
|
||||
$onlineInstallerDir = Join-Path $OutputDir "Installer"
|
||||
$mergeRes = StartAndWait $ilMerge "PlayniteInstaller.exe *.dll /out:`"$installerOutPath`" /ndebug /wildcards" -WorkingDir $onlineInstallerDir
|
||||
if ($mergeRes -ne 0)
|
||||
{
|
||||
throw "ILMerge of installer files failed."
|
||||
}
|
||||
|
||||
Remove-Item $onlineInstallerDir -Recurse
|
||||
|
||||
# -------------------------------------------
|
||||
# Build zip package
|
||||
# -------------------------------------------
|
||||
|
||||
@ -23,6 +23,6 @@
|
||||
<MSBuild
|
||||
Projects="../source/Tools/PlayniteInstaller/PlayniteInstaller.csproj"
|
||||
Targets="Build"
|
||||
Properties="OutputPath=$(OutputPath)/Installer; Configuration=$(Configuration); AllowedReferenceRelatedFileExtensions=none; Platform=AnyCPU" />
|
||||
Properties="OutputPath=$(OutputPath); Configuration=$(Configuration); AllowedReferenceRelatedFileExtensions=none; Platform=AnyCPU" />
|
||||
</Target>
|
||||
</Project>
|
||||
@ -1,6 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
|
||||
</startup>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
|
||||
</startup>
|
||||
<runtime>
|
||||
<loadFromRemoteSources enabled="True" />
|
||||
</runtime>
|
||||
</configuration>
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
<Application x:Class="PlayniteInstaller.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Startup="Application_Startup">
|
||||
Startup="Application_Startup"
|
||||
Exit="Application_Exit">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary Source="Theme/Classic.xaml"/>
|
||||
<ResourceDictionary Source="Classic.xaml"/>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
using Playnite.SDK;
|
||||
using PlayniteInstaller.ViewModels;
|
||||
using Playnite.Common;
|
||||
using Playnite.SDK;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
@ -19,6 +19,7 @@ namespace PlayniteInstaller
|
||||
private static ILogger logger;
|
||||
|
||||
public static string TempDir => Path.Combine(Path.GetTempPath(), "PlayniteInstaller");
|
||||
public static string InstallerDownloadPath => Path.Combine(Path.GetTempPath(), "PlayniteInstaller", "installer.exe");
|
||||
|
||||
private static Version currentVersion;
|
||||
public static Version CurrentVersion
|
||||
@ -37,10 +38,11 @@ namespace PlayniteInstaller
|
||||
private void Application_Startup(object sender, StartupEventArgs e)
|
||||
{
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
NLogLogger.ConfigureLogger();
|
||||
LogManager.Init(new NLogLogProvider());
|
||||
FileSystem.CreateDirectory(App.TempDir);
|
||||
LogManager.Initialize(Path.Combine(App.TempDir, "installer.log"));
|
||||
logger = LogManager.GetLogger();
|
||||
logger.Debug($"Installer started {CurrentVersion}");
|
||||
|
||||
var window = new MainWindow();
|
||||
window.DataContext = new MainViewModel(window);
|
||||
window.ShowDialog();
|
||||
@ -49,6 +51,16 @@ namespace PlayniteInstaller
|
||||
|
||||
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
logger.Error((Exception)e.ExceptionObject, "Unhandled exception occured.");
|
||||
MessageBox.Show(
|
||||
"Unrecoverable error occured and installer will now close.",
|
||||
"Critical error",
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
|
||||
private void Application_Exit(object sender, ExitEventArgs e)
|
||||
{
|
||||
LogManager.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,5 +283,80 @@
|
||||
<Setter Property="FontSize" Value="14" />
|
||||
<Setter Property="BorderBrush" Value="{DynamicResource PopupBorderBrush}" />
|
||||
<Setter Property="BorderThickness" Value="{DynamicResource PopupBorderThickness}" />
|
||||
</Style>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ExpanderDownHeaderStyle" TargetType="{x:Type ToggleButton}">
|
||||
<Setter Property="Foreground" Value="{DynamicResource TextBrush}" />
|
||||
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ToggleButton}">
|
||||
<Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="4" x:Name="CollapsedIcon" FontFamily="Marlett"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
Style="{DynamicResource BaseTextBlockStyle}"
|
||||
Foreground="{DynamicResource GlyphBrush}" FontSize="18" MinWidth="20" Margin="0,0,5,0"
|
||||
Grid.Column="0" TextAlignment="Center" />
|
||||
<TextBlock Text="6" x:Name="ExpandedIcon" FontFamily="Marlett"
|
||||
VerticalAlignment="Center" HorizontalAlignment="Center"
|
||||
Style="{DynamicResource BaseTextBlockStyle}"
|
||||
Foreground="{DynamicResource GlyphBrush}" FontSize="18" MinWidth="20" Margin="0,0,5,0"
|
||||
Visibility="Collapsed"
|
||||
Grid.Column="0" TextAlignment="Center"/>
|
||||
<ContentPresenter Grid.Column="1" VerticalAlignment="Center"
|
||||
SnapsToDevicePixels="True" HorizontalAlignment="Stretch" RecognizesAccessKey="True" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter Property="Visibility" TargetName="ExpandedIcon" Value="Visible" />
|
||||
<Setter Property="Visibility" TargetName="CollapsedIcon" Value="Collapsed" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Opacity" Value="0.75" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="{x:Type Expander}">
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
<Setter Property="BorderBrush" Value="Transparent" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Stretch" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Expander}">
|
||||
<DockPanel>
|
||||
<ToggleButton BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Style="{DynamicResource ExpanderDownHeaderStyle}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
MinHeight="25" DockPanel.Dock="Top"
|
||||
Background="{TemplateBinding Background}"
|
||||
Content="{TemplateBinding Header}"
|
||||
IsChecked="{Binding Path=IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" />
|
||||
<Border x:Name="Border" DockPanel.Dock="Top" Visibility="Collapsed"
|
||||
BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}">
|
||||
<ContentPresenter Focusable="False"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
|
||||
</Border>
|
||||
</DockPanel>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsExpanded" Value="true">
|
||||
<Setter Property="Visibility" TargetName="Border" Value="Visible" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
72
source/Tools/PlayniteInstaller/Converters.cs
Normal file
72
source/Tools/PlayniteInstaller/Converters.cs
Normal file
@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Markup;
|
||||
|
||||
namespace PlayniteInstaller
|
||||
{
|
||||
public class InstallStatusToVisibilityConverter : MarkupExtension, IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return (InstallStatus)value == (InstallStatus)parameter ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public class BooleanToVisibilityConverter : MarkupExtension, IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return Visibility.Collapsed;
|
||||
}
|
||||
|
||||
return ((bool)value) ? Visibility.Visible : Visibility.Collapsed;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return ((Visibility)value) == Visibility.Visible ? true : false;
|
||||
}
|
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public class InvertedBooleanToVisibilityConverter : MarkupExtension, IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var boolValue = (bool)value;
|
||||
return boolValue ? Visibility.Collapsed : Visibility.Visible;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override object ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
127
source/Tools/PlayniteInstaller/Logger.cs
Normal file
127
source/Tools/PlayniteInstaller/Logger.cs
Normal file
@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Playnite.SDK
|
||||
{
|
||||
public class Logger : ILogger
|
||||
{
|
||||
private readonly string loggerName;
|
||||
|
||||
public Logger(string loggerName)
|
||||
{
|
||||
this.loggerName = loggerName;
|
||||
}
|
||||
|
||||
public void Debug(string message)
|
||||
{
|
||||
WriteMessage("|DEBUG: " + message);
|
||||
}
|
||||
|
||||
public void Debug(Exception exception, string message)
|
||||
{
|
||||
WriteMessage(exception, "|DEBUG: " + message);
|
||||
}
|
||||
|
||||
public void Error(string message)
|
||||
{
|
||||
WriteMessage("|ERROR: " + message);
|
||||
}
|
||||
|
||||
public void Error(Exception exception, string message)
|
||||
{
|
||||
WriteMessage(exception, "|ERROR: " + message);
|
||||
}
|
||||
|
||||
public void Info(string message)
|
||||
{
|
||||
WriteMessage("|INFO: " + message);
|
||||
}
|
||||
|
||||
public void Info(Exception exception, string message)
|
||||
{
|
||||
WriteMessage(exception, "|INFO: " + message);
|
||||
}
|
||||
|
||||
public void Trace(string message)
|
||||
{
|
||||
WriteMessage("|TRACE: " + message);
|
||||
}
|
||||
|
||||
public void Trace(Exception exception, string message)
|
||||
{
|
||||
WriteMessage(exception, "|TRACE: " + message);
|
||||
}
|
||||
|
||||
public void Warn(string message)
|
||||
{
|
||||
WriteMessage("|WARN: " + message);
|
||||
}
|
||||
|
||||
public void Warn(Exception exception, string message)
|
||||
{
|
||||
WriteMessage(exception, "|WARN: " + message);
|
||||
}
|
||||
|
||||
private void WriteMessage(string message)
|
||||
{
|
||||
LogManager.WriteMessage(loggerName + message);
|
||||
}
|
||||
|
||||
private void WriteMessage(Exception exception, string message)
|
||||
{
|
||||
LogManager.WriteMessage(loggerName + message);
|
||||
LogManager.WriteMessage(exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public class LogManager
|
||||
{
|
||||
private static FileStream logStream;
|
||||
private static StreamWriter logWriter;
|
||||
private static object writeLock = new object();
|
||||
|
||||
public static void Initialize(string filePath)
|
||||
{
|
||||
logStream = new FileStream(filePath, FileMode.Append, FileAccess.Write);
|
||||
logWriter = new StreamWriter(logStream) { AutoFlush = true };
|
||||
}
|
||||
|
||||
public static void Dispose()
|
||||
{
|
||||
logWriter.Dispose();
|
||||
logStream.Dispose();
|
||||
}
|
||||
|
||||
public static void WriteMessage(string message)
|
||||
{
|
||||
lock (writeLock)
|
||||
{
|
||||
logWriter.WriteLine(DateTime.Now.ToLongTimeString() + "|" + message);
|
||||
}
|
||||
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static ILogger GetLogger()
|
||||
{
|
||||
var className = (new StackFrame(1)).GetMethod().DeclaringType.Name;
|
||||
return GetLogger(className);
|
||||
}
|
||||
|
||||
public static ILogger GetLogger(string loggerName)
|
||||
{
|
||||
return new Logger(loggerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
286
source/Tools/PlayniteInstaller/MainViewModel.cs
Normal file
286
source/Tools/PlayniteInstaller/MainViewModel.cs
Normal file
@ -0,0 +1,286 @@
|
||||
using Playnite.Common;
|
||||
using Playnite.SDK;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace PlayniteInstaller
|
||||
{
|
||||
public enum InstallStatus
|
||||
{
|
||||
Idle,
|
||||
Downloading,
|
||||
Installing
|
||||
}
|
||||
|
||||
public class MainViewModel : ObservableObject
|
||||
{
|
||||
private static readonly ILogger logger = LogManager.GetLogger();
|
||||
private readonly Window windowHost;
|
||||
private readonly List<string> UrlMirrors;
|
||||
private WebClient webClient;
|
||||
|
||||
private InstallStatus status;
|
||||
public InstallStatus Status
|
||||
{
|
||||
get => status;
|
||||
set
|
||||
{
|
||||
status = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private double progressValue;
|
||||
public double ProgressValue
|
||||
{
|
||||
get => progressValue;
|
||||
set
|
||||
{
|
||||
progressValue = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private string destinationFolder;
|
||||
public string DestionationFolder
|
||||
{
|
||||
get => destinationFolder;
|
||||
set
|
||||
{
|
||||
destinationFolder = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private bool portable;
|
||||
public bool Portable
|
||||
{
|
||||
get => portable;
|
||||
set
|
||||
{
|
||||
portable = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public RelayCommand<object> BrowseCommand
|
||||
{
|
||||
get => new RelayCommand<object>((_) =>
|
||||
{
|
||||
Browse();
|
||||
});
|
||||
}
|
||||
|
||||
public RelayCommand<object> InstallCommand
|
||||
{
|
||||
get => new RelayCommand<object>(async (_) =>
|
||||
{
|
||||
await Install();
|
||||
}, (_) => Status == InstallStatus.Idle);
|
||||
}
|
||||
|
||||
public RelayCommand<object> CancelCommand
|
||||
{
|
||||
get => new RelayCommand<object>((_) =>
|
||||
{
|
||||
Cancel();
|
||||
}, (_) => Status != InstallStatus.Installing);
|
||||
}
|
||||
|
||||
public static RelayCommand<string> NavigateUrlCommand
|
||||
{
|
||||
get => new RelayCommand<string>((url) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(url);
|
||||
}
|
||||
catch (Exception e) when (!Debugger.IsAttached)
|
||||
{
|
||||
logger.Error(e, "Failed to open url.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private List<string> ParseList(string input)
|
||||
{
|
||||
return input.Split(new[] { '\r', '\n' }).Where(a => !string.IsNullOrWhiteSpace(a)).ToList();
|
||||
}
|
||||
|
||||
public MainViewModel(Window window)
|
||||
{
|
||||
windowHost = window;
|
||||
DestionationFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Playnite");
|
||||
UrlMirrors = ParseList(Resources.ReadFileFromResource("PlayniteInstaller.installer_mirrors.txt"));
|
||||
logger.Debug("Server mirrors in use:");
|
||||
UrlMirrors.ForEach(a => logger.Debug(a));
|
||||
}
|
||||
|
||||
public void Browse()
|
||||
{
|
||||
var dialog = new FolderBrowserDialog()
|
||||
{
|
||||
Description = "Select Destination Folder...",
|
||||
ShowNewFolderButton = true
|
||||
};
|
||||
|
||||
if (dialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
DestionationFolder = Path.Combine(dialog.SelectedPath, "Playnite");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Install()
|
||||
{
|
||||
if (!FileSystem.CanWriteToFolder(DestionationFolder))
|
||||
{
|
||||
System.Windows.MessageBox.Show(
|
||||
"Can't install Playnite to selected directory, use different path.",
|
||||
"Access error",
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
Status = InstallStatus.Downloading;
|
||||
|
||||
try
|
||||
{
|
||||
FileSystem.DeleteFile(App.InstallerDownloadPath);
|
||||
if (webClient != null)
|
||||
{
|
||||
webClient.Dispose();
|
||||
webClient = null;
|
||||
}
|
||||
|
||||
webClient = new WebClient();
|
||||
var installerUrls = await TryDownloadManifest(UrlMirrors);
|
||||
webClient.DownloadProgressChanged += WebClient_DownloadProgressChanged;
|
||||
if (await TryDownloadInstaller(installerUrls) == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Status = InstallStatus.Installing;
|
||||
var args = string.Format(@"/VERYSILENT /NOCANCEL /DIR=""{0}"" ", DestionationFolder);
|
||||
args += Portable ? "/PORTABLE" : "";
|
||||
logger.Info($"Starting:\n{App.InstallerDownloadPath}\n{args}");
|
||||
await Task.Run(() =>
|
||||
{
|
||||
using (var process = Process.Start(App.InstallerDownloadPath, args))
|
||||
{
|
||||
process.WaitForExit();
|
||||
if (process.ExitCode != 0)
|
||||
{
|
||||
logger.Error($"Installer failed {process.ExitCode}");
|
||||
System.Windows.MessageBox.Show(
|
||||
$"Failed to install Playnite. Error code {process.ExitCode}",
|
||||
"Installation error",
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
Status = InstallStatus.Idle;
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var playnitePath = Path.Combine(DestionationFolder, "Playnite.DesktopApp.exe");
|
||||
if (File.Exists(playnitePath))
|
||||
{
|
||||
Process.Start(playnitePath);
|
||||
}
|
||||
|
||||
windowHost.Close();
|
||||
}
|
||||
catch (Exception e) when (!Debugger.IsAttached)
|
||||
{
|
||||
logger.Error(e, "Failed to download and install Playnite.");
|
||||
System.Windows.MessageBox.Show(
|
||||
$"Failed to install Playnite:\n{e.Message}",
|
||||
"Installation error",
|
||||
MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
Status = InstallStatus.Idle;
|
||||
}
|
||||
finally
|
||||
{
|
||||
webClient?.Dispose();
|
||||
webClient = null;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<List<string>> TryDownloadManifest(List<string> urls)
|
||||
{
|
||||
foreach (var url in urls)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ParseList(await webClient.DownloadStringTaskAsync(url));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error(e, $"Failed to download installer manifest from {url}");
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("Failed to download installer manifest.");
|
||||
}
|
||||
|
||||
private async Task<bool> TryDownloadInstaller(List<string> urls)
|
||||
{
|
||||
foreach (var url in urls)
|
||||
{
|
||||
try
|
||||
{
|
||||
await webClient.DownloadFileTaskAsync(url, App.InstallerDownloadPath);
|
||||
return true;
|
||||
}
|
||||
catch (WebException webExp)
|
||||
{
|
||||
if (webExp.Status == WebExceptionStatus.RequestCanceled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Error(webExp, $"Failed to download installer file from {url}");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Error(e, $"Failed to download installer file from {url}");
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("Failed to download installer file.");
|
||||
}
|
||||
|
||||
private void WebClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
|
||||
{
|
||||
ProgressValue = e.ProgressPercentage;
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
if (Status == InstallStatus.Downloading)
|
||||
{
|
||||
webClient.CancelAsync();
|
||||
webClient.Dispose();
|
||||
webClient = null;
|
||||
Status = InstallStatus.Idle;
|
||||
}
|
||||
else
|
||||
{
|
||||
windowHost.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,53 +3,88 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:local="clr-namespace:PlayniteInstaller"
|
||||
mc:Ignorable="d"
|
||||
WindowStartupLocation="CenterScreen" ResizeMode="NoResize"
|
||||
Background="#252422"
|
||||
Title="Playnite Installer" Width="600" SizeToContent="Height">
|
||||
<Grid Margin="10">
|
||||
<Grid.Resources>
|
||||
|
||||
<StackPanel Margin="10">
|
||||
<StackPanel.Resources>
|
||||
<local:InstallStatusToVisibilityConverter x:Key="InstallStatusToVisibilityConverter" />
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}" />
|
||||
</Grid.Resources>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
|
||||
</Grid.ColumnDefinitions>
|
||||
</StackPanel.Resources>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock FontSize="20" VerticalAlignment="Center" Margin="15,10,10,0">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
|
||||
<Setter Property="Text" Value="Install Playnite" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Status}" Value="{x:Static local:InstallStatus.Downloading}">
|
||||
<Setter Property="Text" Value="Downloading..." />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Status}" Value="{x:Static local:InstallStatus.Installing}">
|
||||
<Setter Property="Text" Value="Installing..." />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
|
||||
<TextBlock Text="Install Playnite" FontSize="20"
|
||||
VerticalAlignment="Center" Grid.Row="0" Margin="15,10,10,10"/>
|
||||
|
||||
|
||||
<DockPanel Grid.Row="1" Margin="5">
|
||||
<TextBlock Text="Destionation Folder" DockPanel.Dock="Left" Margin="10,5,10,5" />
|
||||
<Button Content="Browse..." DockPanel.Dock="Right"
|
||||
<Expander Header="Options" Margin="10" FontSize="{StaticResource FontSize}"
|
||||
Visibility="{Binding Status, Converter={StaticResource InstallStatusToVisibilityConverter}, ConverterParameter={x:Static local:InstallStatus.Idle}}">
|
||||
<StackPanel>
|
||||
<DockPanel Margin="5">
|
||||
<TextBlock Text="Destionation Folder" DockPanel.Dock="Left" Margin="10,5,10,5" />
|
||||
<Button Content="Browse..." DockPanel.Dock="Right"
|
||||
Command="{Binding BrowseCommand}"
|
||||
Padding="10,0,10,0" Margin="10,0,10,0"/>
|
||||
<TextBox DockPanel.Dock="Left" VerticalContentAlignment="Center"
|
||||
<TextBox DockPanel.Dock="Left" VerticalContentAlignment="Center"
|
||||
Text="{Binding DestionationFolder}" />
|
||||
</DockPanel>
|
||||
|
||||
<CheckBox Content="Portable" Grid.Row="2" HorizontalAlignment="Left"
|
||||
IsChecked="{Binding Portable}"
|
||||
ToolTipService.InitialShowDelay="0"
|
||||
ToolTip="Installs Playnite in Portable mode.
All configuration files and game database will be stored in program folder."
|
||||
Margin="15,10,10,10"/>
|
||||
</DockPanel>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Grid.Row="3" HorizontalAlignment="Right"
|
||||
Margin="20,0,15,10">
|
||||
<Button Content="Install" Padding="20,5,20,5" Margin="0,0,10,0"
|
||||
IsDefault="True"
|
||||
Command="{Binding InstallCommand}"/>
|
||||
<CheckBox Content="Portable" HorizontalAlignment="Left"
|
||||
IsChecked="{Binding Portable}"
|
||||
ToolTipService.InitialShowDelay="0"
|
||||
ToolTip="Installs Playnite in Portable mode.
All configuration files and game database will be stored in application's folder."
|
||||
Margin="15,10,10,10"/>
|
||||
</StackPanel>
|
||||
</Expander>
|
||||
|
||||
<ProgressBar HorizontalAlignment="Stretch" Height="25" Margin="15,10,15,10"
|
||||
Minimum="0" Maximum="100" Value="{Binding ProgressValue}">
|
||||
<ProgressBar.Style>
|
||||
<Style TargetType="ProgressBar" BasedOn="{StaticResource {x:Type ProgressBar}}">
|
||||
<Setter Property="IsIndeterminate" Value="False" />
|
||||
<Setter Property="Visibility" Value="Collapsed" />
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Status}" Value="{x:Static local:InstallStatus.Installing}">
|
||||
<Setter Property="IsIndeterminate" Value="True" />
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding Status}" Value="{x:Static local:InstallStatus.Downloading}">
|
||||
<Setter Property="IsIndeterminate" Value="False" />
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ProgressBar.Style>
|
||||
</ProgressBar>
|
||||
|
||||
<DockPanel Margin="15,0,15,10">
|
||||
<Button Content="Cancel" Padding="20,5,20,5"
|
||||
IsCancel="True"
|
||||
IsCancel="True" DockPanel.Dock="Right"
|
||||
Command="{Binding CancelCommand}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Button Content="Install" Padding="20,5,20,5" Margin="0,0,10,0"
|
||||
IsDefault="True" DockPanel.Dock="Right"
|
||||
Command="{Binding InstallCommand}"/>
|
||||
<TextBlock DockPanel.Dock="Left" VerticalAlignment="Center">
|
||||
<Hyperlink Command="{Binding NavigateUrlCommand}"
|
||||
CommandParameter="https://github.com/JosefNemec/Playnite/wiki/Installation-troubleshooting">
|
||||
<Run Text="Having issues?" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
</DockPanel>
|
||||
</StackPanel>
|
||||
</Window>
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PlayniteInstaller
|
||||
{
|
||||
public class AppConfig
|
||||
{
|
||||
public List<string> ServerMirrors { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,112 +0,0 @@
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
using NLog.Targets;
|
||||
using Playnite.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PlayniteInstaller
|
||||
{
|
||||
public class NLogLogger : Playnite.SDK.ILogger
|
||||
{
|
||||
private NLog.Logger logger;
|
||||
|
||||
public NLogLogger(string loggerName)
|
||||
{
|
||||
logger = NLog.LogManager.GetLogger(loggerName);
|
||||
}
|
||||
|
||||
public void Debug(string message)
|
||||
{
|
||||
logger.Debug(message);
|
||||
}
|
||||
|
||||
public void Debug(Exception exception, string message)
|
||||
{
|
||||
logger.Debug(exception, message);
|
||||
}
|
||||
|
||||
public void Error(string message)
|
||||
{
|
||||
logger.Error(message);
|
||||
}
|
||||
|
||||
public void Error(Exception exception, string message)
|
||||
{
|
||||
logger.Error(exception, message);
|
||||
}
|
||||
|
||||
public void Info(string message)
|
||||
{
|
||||
logger.Info(message);
|
||||
}
|
||||
|
||||
public void Info(Exception exception, string message)
|
||||
{
|
||||
logger.Info(exception, message);
|
||||
}
|
||||
|
||||
public void Warn(string message)
|
||||
{
|
||||
logger.Warn(message);
|
||||
}
|
||||
|
||||
public void Warn(Exception exception, string message)
|
||||
{
|
||||
logger.Warn(exception, message);
|
||||
}
|
||||
|
||||
public void Trace(string message)
|
||||
{
|
||||
logger.Trace(message);
|
||||
}
|
||||
|
||||
public void Trace(Exception exception, string message)
|
||||
{
|
||||
logger.Trace(exception, message);
|
||||
}
|
||||
|
||||
public static void ConfigureLogger()
|
||||
{
|
||||
var config = new LoggingConfiguration();
|
||||
#if DEBUG
|
||||
var consoleTarget = new ColoredConsoleTarget()
|
||||
{
|
||||
Layout = @"${message}${onexception:${newline}${exception}}"
|
||||
};
|
||||
|
||||
config.AddTarget("console", consoleTarget);
|
||||
|
||||
var rule1 = new LoggingRule("*", LogLevel.Debug, consoleTarget);
|
||||
config.LoggingRules.Add(rule1);
|
||||
#endif
|
||||
|
||||
FileSystem.CreateDirectory(App.TempDir);
|
||||
var fileTarget = new FileTarget()
|
||||
{
|
||||
FileName = Path.Combine(App.TempDir, "installer.log"),
|
||||
Layout = "${date:format=dd-MM HH\\:mm\\:ss.fff}|${level:uppercase=true:padding=-5}|${message}${onexception:${newline}${exception:format=toString}}",
|
||||
KeepFileOpen = false,
|
||||
Encoding = Encoding.UTF8
|
||||
};
|
||||
|
||||
config.AddTarget("file", fileTarget);
|
||||
|
||||
var rule2 = new LoggingRule("*", LogLevel.Debug, fileTarget);
|
||||
config.LoggingRules.Add(rule2);
|
||||
LogManager.Configuration = config;
|
||||
}
|
||||
}
|
||||
|
||||
public class NLogLogProvider : Playnite.SDK.ILogProvider
|
||||
{
|
||||
Playnite.SDK.ILogger Playnite.SDK.ILogProvider.GetLogger(string loggerName)
|
||||
{
|
||||
return new NLogLogger(loggerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\packages\ILMerge.3.0.41\build\ILMerge.props" Condition="Exists('..\..\packages\ILMerge.3.0.41\build\ILMerge.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
@ -15,6 +14,8 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<TargetFrameworkProfile />
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@ -36,15 +37,12 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>Resources\installer.ico</ApplicationIcon>
|
||||
<ApplicationIcon>playnite-logo-default.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\NLog.4.7.6\lib\net45\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Data" />
|
||||
@ -77,9 +75,6 @@
|
||||
<Compile Include="..\..\PlayniteSDK\ILogger.cs">
|
||||
<Link>Shared\ILogger.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\PlayniteSDK\LogManager.cs">
|
||||
<Link>Shared\LogManager.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\PlayniteSDK\RelayCommand.cs">
|
||||
<Link>Shared\RelayCommand.cs</Link>
|
||||
</Compile>
|
||||
@ -95,9 +90,9 @@
|
||||
<Compile Include="..\..\Playnite\Common\Resources.cs">
|
||||
<Link>Shared\Resources.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Manifests.cs" />
|
||||
<Compile Include="NLogLogger.cs" />
|
||||
<Compile Include="ViewModels\MainViewModel.cs" />
|
||||
<Compile Include="Converters.cs" />
|
||||
<Compile Include="Logger.cs" />
|
||||
<Compile Include="MainViewModel.cs" />
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
@ -110,7 +105,7 @@
|
||||
<DependentUpon>MainWindow.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Page Include="Theme\Classic.xaml">
|
||||
<Page Include="Classic.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
@ -133,20 +128,24 @@
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Include="packages.config" />
|
||||
<None Include="app.manifest">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="App.config" />
|
||||
<None Include="App.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="config.json" />
|
||||
<EmbeddedResource Include="installer_mirrors.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\installer.ico" />
|
||||
<Resource Include="playnite-logo-default.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@ -49,4 +49,4 @@ using System.Windows;
|
||||
// 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.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 361 KiB |
@ -1,104 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Playnite.Common;
|
||||
using Playnite.SDK;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace PlayniteInstaller.ViewModels
|
||||
{
|
||||
public class MainViewModel : ObservableObject
|
||||
{
|
||||
private static readonly ILogger logger = LogManager.GetLogger();
|
||||
private readonly Window windowHost;
|
||||
private readonly AppConfig appConfig;
|
||||
|
||||
private string destinationFolder;
|
||||
public string DestionationFolder
|
||||
{
|
||||
get => destinationFolder;
|
||||
set
|
||||
{
|
||||
destinationFolder = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private bool portable;
|
||||
public bool Portable
|
||||
{
|
||||
get => portable;
|
||||
set
|
||||
{
|
||||
portable = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public RelayCommand<object> BrowseCommand
|
||||
{
|
||||
get => new RelayCommand<object>((a) =>
|
||||
{
|
||||
Browse();
|
||||
});
|
||||
}
|
||||
|
||||
public RelayCommand<object> InstallCommand
|
||||
{
|
||||
get => new RelayCommand<object>((a) =>
|
||||
{
|
||||
Install();
|
||||
});
|
||||
}
|
||||
|
||||
public RelayCommand<object> CancelCommand
|
||||
{
|
||||
get => new RelayCommand<object>((a) =>
|
||||
{
|
||||
Cancel();
|
||||
});
|
||||
}
|
||||
|
||||
public MainViewModel(Window window)
|
||||
{
|
||||
DestionationFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Playnite");
|
||||
windowHost = window;
|
||||
|
||||
var appConfigStr = Resources.ReadFileFromResource("PlayniteInstaller.config.json");
|
||||
logger.Info(appConfigStr);
|
||||
appConfig = JsonConvert.DeserializeObject<AppConfig>(appConfigStr);
|
||||
}
|
||||
|
||||
public void Browse()
|
||||
{
|
||||
var dialog = new FolderBrowserDialog()
|
||||
{
|
||||
Description = "Select Destination Folder...",
|
||||
ShowNewFolderButton = true
|
||||
};
|
||||
|
||||
if (dialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
DestionationFolder = dialog.SelectedPath;
|
||||
}
|
||||
}
|
||||
|
||||
public void Install()
|
||||
{
|
||||
windowHost.Close();
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
windowHost.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
23
source/Tools/PlayniteInstaller/app.manifest
Normal file
23
source/Tools/PlayniteInstaller/app.manifest
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="Playnite.DesktopApp"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
@ -1,6 +0,0 @@
|
||||
{
|
||||
"ServerMirrors": [
|
||||
"https://localhost/installer/",
|
||||
"https://localhost:8081/installer/"
|
||||
]
|
||||
}
|
||||
2
source/Tools/PlayniteInstaller/installer_mirrors.txt
Normal file
2
source/Tools/PlayniteInstaller/installer_mirrors.txt
Normal file
@ -0,0 +1,2 @@
|
||||
https://raw.githubusercontent.com/JosefNemec/PlayniteWeb/master/manifests/installer_mirrors.txt
|
||||
https://playnite.link/download/installer_mirrors.txt
|
||||
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="ILMerge" version="3.0.41" targetFramework="net462" />
|
||||
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net462" />
|
||||
<package id="NLog" version="4.7.6" targetFramework="net462" />
|
||||
</packages>
|
||||
BIN
source/Tools/PlayniteInstaller/playnite-logo-default.ico
Normal file
BIN
source/Tools/PlayniteInstaller/playnite-logo-default.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
Loading…
x
Reference in New Issue
Block a user