-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
certificates and windows app runtime
- Loading branch information
Showing
8 changed files
with
280 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Net.Http; | ||
using System.Security.Cryptography.X509Certificates; | ||
using System.Threading.Tasks; | ||
|
||
namespace Snap.Hutao.Deployment; | ||
|
||
internal static class Certificate | ||
{ | ||
private const string CertificateName = "GlobalSign Code Signing Root R45"; | ||
private const string CertificateUrl = "https://secure.globalsign.com/cacert/codesigningrootr45.crt"; | ||
|
||
public static async Task EnsureGlobalSignCodeSigningRootR45Async() | ||
{ | ||
using (X509Store store = new(StoreName.Root, StoreLocation.LocalMachine)) | ||
{ | ||
store.Open(OpenFlags.ReadWrite); | ||
if (store.Certificates.Any(cert => cert.FriendlyName == CertificateName)) | ||
{ | ||
Console.WriteLine("Certificate [GlobalSign Code Signing Root R45] found"); | ||
return; | ||
} | ||
|
||
Console.WriteLine("Required Certificate [GlobalSign Code Signing Root R45] not found, download from GlobalSign"); | ||
|
||
using (HttpClient httpClient = new()) | ||
{ | ||
byte[] rawData = await httpClient.GetByteArrayAsync(CertificateUrl).ConfigureAwait(false); | ||
|
||
Console.WriteLine(""" | ||
正在向本地计算机/受信任的根证书颁发机构添加证书 | ||
如果你无法理解弹窗中的文本,请点击 [是] | ||
Adding certificate to LocalMachine/ThirdParty Root CA store, | ||
please click [yes] on the [Security Waring] dialog | ||
For more security information, please visit the url down below | ||
https://support.globalsign.com/ca-certificates/root-certificates/globalsign-root-certificates | ||
"""); | ||
store.Add(new X509Certificate2(rawData)); | ||
} | ||
} | ||
} | ||
} |
6 changes: 3 additions & 3 deletions
6
...Hutao.Deployment/PackageDownloadStatus.cs → src/Snap.Hutao.Deployment/DownloadStatus.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
using System; | ||
using System.Net.Http; | ||
using System.Threading.Tasks; | ||
|
||
namespace Snap.Hutao.Deployment; | ||
|
||
internal static class PackageDownload | ||
{ | ||
public static async Task DownloadPackageAsync(string packagePath) | ||
{ | ||
using (HttpClient httpClient = new()) | ||
{ | ||
HttpShardCopyWorkerOptions<DownloadStatus> options = new() | ||
{ | ||
HttpClient = httpClient, | ||
SourceUrl = "https://api.snapgenshin.com/patch/hutao/download", | ||
DestinationFilePath = packagePath, | ||
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); | ||
} | ||
} | ||
|
||
static void ConsoleWriteProgress(DownloadStatus status) | ||
{ | ||
Console.Write($"\r{status.ProgressDescription}"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using System; | ||
using Windows.ApplicationModel; | ||
|
||
namespace Snap.Hutao.Deployment; | ||
|
||
internal static class PackageVersionExtension | ||
{ | ||
public static Version ToVersion(this PackageVersion packageVersion) | ||
{ | ||
return new Version(packageVersion.Major, packageVersion.Minor, packageVersion.Build, packageVersion.Revision); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
using System; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.IO.Compression; | ||
using System.Net.Http; | ||
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) | ||
{ | ||
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 (CheckRuntimeInstalled(packageName, msixVersion)) | ||
{ | ||
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); | ||
} | ||
|
||
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 bool CheckRuntimeInstalled(string packageName, string msixVersion) | ||
{ | ||
Version msixMinVersion = new(msixVersion); | ||
|
||
foreach (Windows.ApplicationModel.Package installed in new PackageManager().FindPackages()) | ||
{ | ||
if (installed.Id.Name == packageName && installed.Id.Version.ToVersion() >= msixMinVersion) | ||
{ | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
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); | ||
} | ||
} | ||
|
||
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); | ||
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(); | ||
} |