mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.Deployment.git
synced 2025-11-19 21:08:45 +08:00
globalization
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Snap.Hutao.Deployment.Runtime</id>
|
<id>Snap.Hutao.Deployment.Runtime</id>
|
||||||
<version>1.15.3</version>
|
<version>1.16.0</version>
|
||||||
<authors>DGP Studio</authors>
|
<authors>DGP Studio</authors>
|
||||||
<developmentDependency>true</developmentDependency>
|
<developmentDependency>true</developmentDependency>
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
|
|||||||
Binary file not shown.
@@ -18,23 +18,30 @@ internal static class Certificate
|
|||||||
store.Open(OpenFlags.ReadWrite);
|
store.Open(OpenFlags.ReadWrite);
|
||||||
if (store.Certificates.Any(cert => cert.FriendlyName == CertificateName))
|
if (store.Certificates.Any(cert => cert.FriendlyName == CertificateName))
|
||||||
{
|
{
|
||||||
Console.WriteLine("Certificate [GlobalSign Code Signing Root R45] found");
|
Console.WriteLine("""
|
||||||
|
已找到证书 [GlobalSign Code Signing Root R45]
|
||||||
|
Certificate [GlobalSign Code Signing Root R45] found
|
||||||
|
""");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("Required Certificate [GlobalSign Code Signing Root R45] not found, download from GlobalSign");
|
Console.WriteLine("""
|
||||||
|
无法找到所需证书 [GlobalSign Code Signing Root R45],正在从 GlobalSign 下载
|
||||||
|
Required Certificate [GlobalSign Code Signing Root R45] not found, downloading from GlobalSign
|
||||||
|
""");
|
||||||
|
|
||||||
using (HttpClient httpClient = new())
|
using (HttpClient httpClient = new())
|
||||||
{
|
{
|
||||||
byte[] rawData = await httpClient.GetByteArrayAsync(CertificateUrl).ConfigureAwait(false);
|
byte[] rawData = await httpClient.GetByteArrayAsync(CertificateUrl).ConfigureAwait(false);
|
||||||
|
|
||||||
Console.WriteLine("""
|
Console.WriteLine("""
|
||||||
正在向本地计算机/受信任的根证书颁发机构添加证书
|
正在向 本地计算机/受信任的根证书颁发机构 添加证书
|
||||||
如果你无法理解弹窗中的文本,请点击 [是]
|
如果你无法理解弹窗中的文本,请点击 [是]
|
||||||
|
|
||||||
Adding certificate to LocalMachine/ThirdParty Root CA store,
|
Adding certificate to LocalMachine/ThirdParty Root CA store,
|
||||||
please click [yes] on the [Security Waring] dialog
|
please click [yes] on the [Security Waring] dialog
|
||||||
|
|
||||||
|
关于更多安全信息,请查看下方的网址
|
||||||
For more security information, please visit the url down below
|
For more security information, please visit the url down below
|
||||||
https://support.globalsign.com/ca-certificates/root-certificates/globalsign-root-certificates
|
https://support.globalsign.com/ca-certificates/root-certificates/globalsign-root-certificates
|
||||||
""");
|
""");
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ internal static partial class Invocation
|
|||||||
ArgumentException.ThrowIfNullOrEmpty(path);
|
ArgumentException.ThrowIfNullOrEmpty(path);
|
||||||
|
|
||||||
Console.WriteLine($"""
|
Console.WriteLine($"""
|
||||||
Snap Hutao Deployment Tool [1.15.3]
|
Snap Hutao Deployment Tool [1.16.0]
|
||||||
PackagePath: {path}
|
PackagePath: {path}
|
||||||
FamilyName: {name}
|
FamilyName: {name}
|
||||||
------------------------------------------------------------
|
------------------------------------------------------------
|
||||||
@@ -35,7 +35,10 @@ internal static partial class Invocation
|
|||||||
{
|
{
|
||||||
if (!File.Exists(path))
|
if (!File.Exists(path))
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Package file not found.");
|
Console.WriteLine("""
|
||||||
|
未找到包文件。
|
||||||
|
Package file not found.
|
||||||
|
""");
|
||||||
|
|
||||||
if (isUpdateMode)
|
if (isUpdateMode)
|
||||||
{
|
{
|
||||||
@@ -44,13 +47,15 @@ internal static partial class Invocation
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Console.WriteLine("Start downloading package...");
|
Console.WriteLine("""
|
||||||
|
开始下载包文件...
|
||||||
|
Start downloading package...
|
||||||
|
""");
|
||||||
await PackageDownload.DownloadPackageAsync(path).ConfigureAwait(false);
|
await PackageDownload.DownloadPackageAsync(path).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await Certificate.EnsureGlobalSignCodeSigningRootR45Async().ConfigureAwait(false);
|
await Certificate.EnsureGlobalSignCodeSigningRootR45Async().ConfigureAwait(false);
|
||||||
await WindowsAppSDKDependency.EnsureAsync(path).ConfigureAwait(false);
|
|
||||||
await RunDeploymentCoreAsync(path, name, isUpdateMode).ConfigureAwait(false);
|
await RunDeploymentCoreAsync(path, name, isUpdateMode).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -68,7 +73,10 @@ internal static partial class Invocation
|
|||||||
|
|
||||||
private static async Task RunDeploymentCoreAsync(string path, string? name, bool isUpdateMode)
|
private static async Task RunDeploymentCoreAsync(string path, string? name, bool isUpdateMode)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Initializing PackageManager...");
|
Console.WriteLine("""
|
||||||
|
初始化 PackageManager...
|
||||||
|
Initializing PackageManager...
|
||||||
|
""");
|
||||||
PackageManager packageManager = new();
|
PackageManager packageManager = new();
|
||||||
AddPackageOptions addPackageOptions = new()
|
AddPackageOptions addPackageOptions = new()
|
||||||
{
|
{
|
||||||
@@ -76,7 +84,10 @@ internal static partial class Invocation
|
|||||||
RetainFilesOnFailure = true,
|
RetainFilesOnFailure = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
Console.WriteLine("Start deploying...");
|
Console.WriteLine("""
|
||||||
|
开始部署...
|
||||||
|
Start deploying...
|
||||||
|
""");
|
||||||
IProgress<DeploymentProgress> progress = new Progress<DeploymentProgress>(p =>
|
IProgress<DeploymentProgress> progress = new Progress<DeploymentProgress>(p =>
|
||||||
{
|
{
|
||||||
Console.WriteLine($"[Deploying]: State: {p.state} Progress: {p.percentage}%");
|
Console.WriteLine($"[Deploying]: State: {p.state} Progress: {p.percentage}%");
|
||||||
@@ -88,10 +99,16 @@ internal static partial class Invocation
|
|||||||
|
|
||||||
if (result.IsRegistered)
|
if (result.IsRegistered)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Package deployed.");
|
Console.WriteLine("""
|
||||||
|
包部署成功。
|
||||||
|
Package deployed.
|
||||||
|
""");
|
||||||
if (string.IsNullOrEmpty(name))
|
if (string.IsNullOrEmpty(name))
|
||||||
{
|
{
|
||||||
Console.WriteLine("FamilyName not provided, enumerating packages.");
|
Console.WriteLine("""
|
||||||
|
未提供 FamilyName,正在枚举包。
|
||||||
|
FamilyName not provided, enumerating packages.
|
||||||
|
""");
|
||||||
|
|
||||||
foreach (Windows.ApplicationModel.Package package in packageManager.FindPackages())
|
foreach (Windows.ApplicationModel.Package package in packageManager.FindPackages())
|
||||||
{
|
{
|
||||||
@@ -114,7 +131,10 @@ internal static partial class Invocation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("Starting app...");
|
Console.WriteLine("""
|
||||||
|
正在启动应用...
|
||||||
|
Starting app...
|
||||||
|
""");
|
||||||
Process.Start(new ProcessStartInfo()
|
Process.Start(new ProcessStartInfo()
|
||||||
{
|
{
|
||||||
UseShellExecute = true,
|
UseShellExecute = true,
|
||||||
@@ -135,7 +155,10 @@ internal static partial class Invocation
|
|||||||
{
|
{
|
||||||
if (!isUpdateMode)
|
if (!isUpdateMode)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Press enter to exit...");
|
Console.WriteLine("""
|
||||||
|
按下回车键退出...
|
||||||
|
Press enter to exit...
|
||||||
|
""");
|
||||||
while (Console.ReadKey(true).Key != ConsoleKey.Enter)
|
while (Console.ReadKey(true).Key != ConsoleKey.Enter)
|
||||||
{
|
{
|
||||||
//Pending enter key
|
//Pending enter key
|
||||||
|
|||||||
@@ -1,214 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.ServiceProcess;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Windows.Management.Deployment;
|
|
||||||
|
|
||||||
namespace Snap.Hutao.Deployment;
|
|
||||||
|
|
||||||
internal static partial class WindowsAppSDKDependency
|
|
||||||
{
|
|
||||||
private const string SDKInstallerDownloadFormat = "https://aka.ms/windowsappsdk/{0}/{1}/windowsappruntimeinstall-x64.exe";
|
|
||||||
|
|
||||||
public static async Task EnsureAsync(string packagePath)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (FileStream packageStream = File.OpenRead(packagePath))
|
|
||||||
{
|
|
||||||
using (ZipArchive package = new(packageStream, ZipArchiveMode.Read))
|
|
||||||
{
|
|
||||||
(string packageName, string msixVersion) = await ExtractRuntimePackageNameAndMsixMinVersionFromAppManifestAsync(package).ConfigureAwait(false);
|
|
||||||
if (string.IsNullOrEmpty(packageName) || string.IsNullOrEmpty(msixVersion))
|
|
||||||
{
|
|
||||||
Console.WriteLine("No Windows App Runtime version found in Msix/AppxManifest.xml");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (await CheckRuntimeInstalledAndVerifyAsync(packageName, msixVersion).ConfigureAwait(false))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string sdkVersion = await ExtractSDKVersionFromDepsJsonAsync(package).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(sdkVersion))
|
|
||||||
{
|
|
||||||
Console.WriteLine("No Windows App SDK version found in Msix/Snap.Hutao.deps.json");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine("Start downloading SDK installer...");
|
|
||||||
await DownloadWindowsAppRuntimeInstallAndInstallAsync(sdkVersion).ConfigureAwait(false);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (InvalidDataException)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Msix Package corrupted, please re-launch Deployment and try again");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
File.Delete(packagePath);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task<string> ExtractSDKVersionFromDepsJsonAsync(ZipArchive package)
|
|
||||||
{
|
|
||||||
ZipArchiveEntry? depsJson = package.GetEntry("Snap.Hutao.deps.json");
|
|
||||||
ArgumentNullException.ThrowIfNull(depsJson);
|
|
||||||
|
|
||||||
using (StreamReader reader = new(depsJson.Open()))
|
|
||||||
{
|
|
||||||
while (await reader.ReadLineAsync().ConfigureAwait(false) is { } line)
|
|
||||||
{
|
|
||||||
if (WindowsAppSDKVersion().Match(line) is { Success: true } match)
|
|
||||||
{
|
|
||||||
string sdkVersion = match.Groups[1].Value;
|
|
||||||
Console.WriteLine($"Using Windows App SDK version: {sdkVersion}");
|
|
||||||
return sdkVersion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task<bool> CheckRuntimeInstalledAndVerifyAsync(string packageName, string msixVersion)
|
|
||||||
{
|
|
||||||
Version msixMinVersion = new(msixVersion);
|
|
||||||
|
|
||||||
List<bool> results = [];
|
|
||||||
|
|
||||||
foreach (Windows.ApplicationModel.Package installed in new PackageManager().FindPackages())
|
|
||||||
{
|
|
||||||
if (installed.Id.Name == packageName && installed.Id.Version.ToVersion() >= msixMinVersion)
|
|
||||||
{
|
|
||||||
results.Add(await installed.VerifyContentIntegrityAsync());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return results.Count > 0 && results.Aggregate((result, element) => result || element);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task DownloadWindowsAppRuntimeInstallAndInstallAsync(string version)
|
|
||||||
{
|
|
||||||
string sdkInstallerPath = Path.Combine(Path.GetTempPath(), "windowsappruntimeinstall-x64.exe");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
using (HttpClient httpClient = new())
|
|
||||||
{
|
|
||||||
HttpShardCopyWorkerOptions<DownloadStatus> options = new()
|
|
||||||
{
|
|
||||||
HttpClient = httpClient,
|
|
||||||
SourceUrl = string.Format(SDKInstallerDownloadFormat, MajorMinorVersion().Match(version).Value, version),
|
|
||||||
DestinationFilePath = sdkInstallerPath,
|
|
||||||
StatusFactory = (bytesRead, totalBytes) => new DownloadStatus(bytesRead, totalBytes),
|
|
||||||
};
|
|
||||||
|
|
||||||
using (HttpShardCopyWorker<DownloadStatus> worker = await HttpShardCopyWorker<DownloadStatus>.CreateAsync(options).ConfigureAwait(false))
|
|
||||||
{
|
|
||||||
Progress<DownloadStatus> progress = new(ConsoleWriteProgress);
|
|
||||||
await worker.CopyAsync(progress).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ServiceController serviceController = new("appxsvc");
|
|
||||||
if (serviceController.CanStop)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Stopping AppxSvc...");
|
|
||||||
serviceController.Stop();
|
|
||||||
serviceController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(5));
|
|
||||||
|
|
||||||
if (serviceController.Status is not ServiceControllerStatus.Stopped)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Can not stop AppxSvc, timeout...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine("Can not stop AppxSvc, disallowed...");
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLine("Start installing SDK...");
|
|
||||||
Process installerProcess = new()
|
|
||||||
{
|
|
||||||
StartInfo = new()
|
|
||||||
{
|
|
||||||
FileName = sdkInstallerPath,
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
RedirectStandardError = true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
using (installerProcess)
|
|
||||||
{
|
|
||||||
installerProcess.OutputDataReceived += (sender, e) => Console.WriteLine(e.Data);
|
|
||||||
installerProcess.ErrorDataReceived += (sender, e) => Console.WriteLine(e.Data);
|
|
||||||
installerProcess.Start();
|
|
||||||
Console.WriteLine("-----> WindowsAppRuntimeInstall Output begin");
|
|
||||||
installerProcess.BeginOutputReadLine();
|
|
||||||
installerProcess.BeginErrorReadLine();
|
|
||||||
|
|
||||||
await installerProcess.WaitForExitAsync().ConfigureAwait(false);
|
|
||||||
Marshal.ThrowExceptionForHR(installerProcess.ExitCode);
|
|
||||||
Console.WriteLine("<----- WindowsAppRuntimeInstall Output end");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
if (File.Exists(sdkInstallerPath))
|
|
||||||
{
|
|
||||||
File.Delete(sdkInstallerPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ConsoleWriteProgress(DownloadStatus status)
|
|
||||||
{
|
|
||||||
Console.Write($"\r{status.ProgressDescription}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task<(string PackageName, string MsixVersion)> ExtractRuntimePackageNameAndMsixMinVersionFromAppManifestAsync(ZipArchive package)
|
|
||||||
{
|
|
||||||
ZipArchiveEntry? appxManifest = package.GetEntry("AppxManifest.xml");
|
|
||||||
ArgumentNullException.ThrowIfNull(appxManifest);
|
|
||||||
|
|
||||||
using (StreamReader reader = new(appxManifest.Open()))
|
|
||||||
{
|
|
||||||
while (await reader.ReadLineAsync().ConfigureAwait(false) is { } line)
|
|
||||||
{
|
|
||||||
if (WindowsAppRuntimeMsixMinVersion().Match(line) is { Success: true } match)
|
|
||||||
{
|
|
||||||
string packageName = match.Groups[1].Value;
|
|
||||||
string msixVersion = match.Groups[2].Value;
|
|
||||||
Console.WriteLine($"Using {packageName} version: {msixVersion}");
|
|
||||||
return (packageName, msixVersion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (string.Empty, string.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
[GeneratedRegex("<PackageDependency Name=\"(Microsoft\\.WindowsAppRuntime.+?)\" MinVersion=\"(.+?)\"")]
|
|
||||||
private static partial Regex WindowsAppRuntimeMsixMinVersion();
|
|
||||||
|
|
||||||
[GeneratedRegex("\"Microsoft\\.WindowsAppSDK\": \"(.+?)\",")]
|
|
||||||
private static partial Regex WindowsAppSDKVersion();
|
|
||||||
|
|
||||||
[GeneratedRegex(@"\d+\.\d+")]
|
|
||||||
private static partial Regex MajorMinorVersion();
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user