0% found this document useful (0 votes)
38 views6 pages

3 KCQ XBZ

The document is a C# code implementation for a bootstrapper installer that checks for updates and downloads necessary software components. It includes methods for verifying the installation of WebView2, downloading the latest bootstrapper and software, and handling errors during these processes. The installer uses various endpoints to fetch configuration data and manage software versions efficiently.

Uploaded by

asdas4a4d4s4
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
38 views6 pages

3 KCQ XBZ

The document is a C# code implementation for a bootstrapper installer that checks for updates and downloads necessary software components. It includes methods for verifying the installation of WebView2, downloading the latest bootstrapper and software, and handling errors during these processes. The installer uses various endpoints to fetch configuration data and manage software versions efficiently.

Uploaded by

asdas4a4d4s4
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6

using Microsoft.

Win32;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;

#nullable disable
namespace Bootstrapper
{
internal class Installer
{
private readonly double currentInstallerVersion = 2.18;
private readonly string[] solara_endpoints = new string[4]
{
"https://getsolara.dev/api/endpoint.json",
"https://api.getsolara.gg/api/endpoint.json",
"https://pastebin.com/raw/h8GnGH0Y",

"https://gitlab.com/cmd-softworks1/a/-/snippets/4768754/raw/main/endpoint.json"
};
private string current;

public string BootstrapperVersion { get; private set; }

public string SupportedClient { get; private set; }

public string SoftwareVersion { get; private set; }

public string BootstrapperUrl { get; private set; }

public string SoftwareUrl { get; private set; }

public string VersionUrl { get; private set; }

public string ClientHash { get; private set; }

public string Changelog { get; private set; }

public static bool WebViewIsInstalled()


{
using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("Software\\
WOW6432Node\\Microsoft\\EdgeUpdate\\Clients\\{F3017226-FE2A-4295-8BDF-
00C3A9A7E4C5}"))
return registryKey != null && registryKey.GetValue("pv") != null;
}

private async Task DownloadAndStartNewBootstrapper(double newVersion)


{
try
{
string newFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
string.Format("Bootstrapper_v{0}.exe", (object) newVersion));
using (HttpClient httpClient = new HttpClient((HttpMessageHandler) new
HttpClientHandler()
{
PreAuthenticate = true,
ServerCertificateCustomValidationCallback = (Func<HttpRequestMessage,
X509Certificate2, X509Chain, SslPolicyErrors, bool>) ((message, cert, chain,
errors) => true)
}))
{
HttpResponseMessage async = await
httpClient.GetAsync(this.BootstrapperUrl);
async.EnsureSuccessStatusCode();
using (FileStream fs = new FileStream(newFileName, FileMode.Create,
FileAccess.Write, FileShare.None))
await async.Content.CopyToAsync((Stream) fs);
}
Process process = await Task.Run<Process>((Func<Process>) (() =>
Process.Start(newFileName, Process.GetCurrentProcess().ProcessName)));
await Task.Delay(500);
Application.Current.Shutdown();
}
catch (Exception ex)
{
int num = (int) MessageBox.Show("An error occurred while updating the
bootstrapper:\n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Hand);
}
}

public async Task DownloadSolara(string folderPath)


{
try
{
string parentDirectory = Directory.GetParent(folderPath).FullName;
string tempZipPath = Path.Combine(parentDirectory, "SolaraTemp.zip");
using (HttpClient httpClient = new HttpClient((HttpMessageHandler) new
HttpClientHandler()
{
PreAuthenticate = true,
ServerCertificateCustomValidationCallback = (Func<HttpRequestMessage,
X509Certificate2, X509Chain, SslPolicyErrors, bool>) ((message, cert, chain,
errors) => true)
}))
{
HttpResponseMessage async = await httpClient.GetAsync(this.SoftwareUrl);
async.EnsureSuccessStatusCode();
using (FileStream fs = new FileStream(tempZipPath, FileMode.Create,
FileAccess.Write, FileShare.None))
await async.Content.CopyToAsync((Stream) fs);
}
if (Directory.Exists(folderPath))
Directory.Delete(folderPath, true);
ZipFile.ExtractToDirectory(tempZipPath, parentDirectory);
File.Delete(tempZipPath);
parentDirectory = (string) null;
tempZipPath = (string) null;
}
catch (Exception ex1)
{
try
{
int num1 = ((IEnumerable<string>)
this.solara_endpoints).ToList<string>().IndexOf(this.current);
if (num1 < 0 || num1 >= this.solara_endpoints.Length - 1)
throw new InvalidOperationException("No more endpoints available in the
list.");
int num2 = await
this.TryFetchEndpointDataAsync(this.solara_endpoints[num1 + 1]) ? 1 : 0;
await this.DownloadSolara(folderPath);
}
catch (Exception ex2)
{
int num = (int) MessageBox.Show("An error occurred during the download or
extraction process: " + ex2.Message, "Error", MessageBoxButton.OK,
MessageBoxImage.Hand);
}
}
}

public async Task CheckAndUpdateSolaraAsync()


{
Installer.Config config =
JsonSerializer.Deserialize<Installer.Config>(File.ReadAllText("CONFIG"),
(JsonSerializerOptions) null);
if (!Directory.Exists(config.FolderPath))
await this.DownloadSolara(config.FolderPath);
else if (Directory.Exists(Path.Combine(config.FolderPath, "bin")) &&
File.Exists(Path.Combine(Path.Combine(config.FolderPath, "bin"), "version.txt")) &&
File.Exists(Path.Combine(config.FolderPath, "Solara.exe")) &&
File.Exists(Path.Combine(config.FolderPath, "SolaraV3.dll")))
{
double result1;
double result2;
if (!double.TryParse(File.ReadAllText(Path.Combine(config.FolderPath,
"bin", "version.txt")), NumberStyles.Float, (IFormatProvider)
CultureInfo.InvariantCulture, out result1) || !
double.TryParse(this.SoftwareVersion, NumberStyles.Float, (IFormatProvider)
CultureInfo.InvariantCulture, out result2) || result1 >= result2)
return;
await this.DownloadSolara(config.FolderPath);
}
else
await this.DownloadSolara(config.FolderPath);
}

public async Task CheckAndUpdateBootstrapperAsync()


{
double result;
if (double.TryParse(this.BootstrapperVersion, NumberStyles.Float,
(IFormatProvider) CultureInfo.InvariantCulture, out result))
{
if (this.currentInstallerVersion >= result)
return;
if (MessageBox.Show(string.Format("A new bootstrapper version ({0}) is
available. Would you like to update?", (object) result), "Update Available",
MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
await this.DownloadAndStartNewBootstrapper(result);
else
Application.Current.Shutdown();
}
else
{
int num = (int) MessageBox.Show("Failed to parse the bootstrapper version
from the server.", "Error", MessageBoxButton.OK, MessageBoxImage.Hand);
}
}

private static async Task DownloadWebview()


{
string requestUri = "https://go.microsoft.com/fwlink/p/?LinkId=2124703";
string installerPath = Path.Combine(Path.GetTempPath(),
"MicrosoftEdgeWebview2Setup.exe");
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage response = await client.GetAsync(requestUri,
HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode();
using (FileStream fileStream = new FileStream(installerPath,
FileMode.Create, FileAccess.Write, FileShare.None))
await response.Content.CopyToAsync((Stream) fileStream);
}
}
using (Process installerProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = installerPath,
Arguments = "/silent /install",
UseShellExecute = false,
CreateNoWindow = true
}
})
{
installerProcess.Start();
await installerProcess.WaitForProcessExitAsync();
if (installerProcess.ExitCode != 0)
{
int num = (int) MessageBox.Show(string.Format("Couldn't install WebView2
Runtime. Error Code: {0}", (object) installerProcess.ExitCode));
}
}
installerPath = (string) null;
}

public async Task<bool> StartAsync(Page3 window)


{
if (!Installer.WebViewIsInstalled())
{
window.SetStatus("Installing WebView2 Runtime - this may take a few
minutes...");
await Installer.DownloadWebview();
window.SetStatus("Getting Solara ready, sit tight...");
}
string[] strArray = this.solara_endpoints;
for (int index = 0; index < strArray.Length; ++index)
{
if (await this.TryFetchEndpointDataAsync(strArray[index]))
{
double result;
if (!double.TryParse(this.BootstrapperVersion, NumberStyles.Float,
(IFormatProvider) CultureInfo.InvariantCulture, out result))
return false;
if (result > this.currentInstallerVersion)
{
await this.CheckAndUpdateBootstrapperAsync();
return true;
}
await this.CheckAndUpdateSolaraAsync();
return true;
}
}
strArray = (string[]) null;
int num = (int) MessageBox.Show("Unable to connect to servers.", "Error",
MessageBoxButton.OK, MessageBoxImage.Hand);
return false;
}

private async Task<bool> TryFetchEndpointDataAsync(string endpoint)


{
this.current = endpoint;
try
{
Installer.EndpointData data =
JsonConvert.DeserializeObject<Installer.EndpointData>(await new
HttpClient((HttpMessageHandler) new HttpClientHandler()
{
PreAuthenticate = true,
ServerCertificateCustomValidationCallback = (Func<HttpRequestMessage,
X509Certificate2, X509Chain, SslPolicyErrors, bool>) ((message, cert, chain,
errors) => true)
}).GetStringAsync(endpoint));
if (data != null)
{
this.StoreData(data);
return true;
}
}
catch (Exception ex)
{
}
return false;
}

private void StoreData(Installer.EndpointData data)


{
this.BootstrapperVersion = data.BootstrapperVersion;
this.SupportedClient = data.SupportedClient;
this.SoftwareVersion = data.SoftwareVersion;
this.BootstrapperUrl = data.BootstrapperUrl;
this.SoftwareUrl = data.SoftwareUrl;
this.VersionUrl = data.VersionUrl;
this.ClientHash = data.ClientHash;
this.Changelog = data.Changelog;
}

public class Config


{
public bool DontShowChangeLogs { get; set; }

public string FolderPath { get; set; }

public bool SetupAlreadyDone { get; set; }


}

private class EndpointData


{
public string BootstrapperVersion { get; set; }

public string SupportedClient { get; set; }

public string SoftwareVersion { get; set; }

public string BootstrapperUrl { get; set; }

public string SoftwareUrl { get; set; }

public string VersionUrl { get; set; }

public string ClientHash { get; set; }

public string Changelog { get; set; }


}
}
}

You might also like