Upgraded to .NET 10 (#1147)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-11-01 20:32:16 +01:00
1 parent faae2951f7
commit fc7399e81b
327 files changed
+3059 -3049

No files matched your search

+5 -6
View File
@@ -39,12 +39,11 @@ public sealed class Encryption(ILogger<Encryption> logger, byte[] secretPassword
// Derive key and iv vector: the operations take several seconds. Thus, using a task:
await Task.Run(() =>
{
using var keyVectorObj = new Rfc2898DeriveBytes(secretPassword, secretKeySalt, ITERATIONS, HashAlgorithmName.SHA512);
var keyBytes = keyVectorObj.GetBytes(32); // the max valid key length = 256 bit = 32 bytes
var ivBytes = keyVectorObj.GetBytes(16); // the only valid block size = 128 bit = 16 bytes
Array.Copy(keyBytes, this.key, this.key.Length);
Array.Copy(ivBytes, this.iv, this.iv.Length);
// The max valid key length = 256 bit = 32 bytes, and the only valid block size = 128 bit = 16 bytes:
var keyVectorBytes = Rfc2898DeriveBytes.Pbkdf2(secretPassword, secretKeySalt, ITERATIONS, HashAlgorithmName.SHA512, this.key.Length + this.iv.Length);
Array.Copy(keyVectorBytes, 0, this.key, 0, this.key.Length);
Array.Copy(keyVectorBytes, this.key.Length, this.iv, 0, this.iv.Length);
});
var initDuration = stopwatch.Elapsed;
@@ -292,11 +292,11 @@ public sealed class EnterpriseEncryption
/// </summary>
private Aes CreateAesV1(byte[] salt)
{
// Derive key and IV using PBKDF2:
using var keyDerivation = new Rfc2898DeriveBytes(this.secretKey!, salt, V1_ITERATIONS, HashAlgorithmName.SHA512);
// Derive key and IV using PBKDF2, the first 32 bytes for AES-256 and the last 16 for its block size:
var keyAndIv = Rfc2898DeriveBytes.Pbkdf2(this.secretKey!, salt, V1_ITERATIONS, HashAlgorithmName.SHA512, 48);
var aes = Aes.Create();
aes.Key = keyDerivation.GetBytes(32); // AES-256
aes.IV = keyDerivation.GetBytes(16); // AES block size
aes.Key = keyAndIv[..32];
aes.IV = keyAndIv[32..];
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
return aes;
@@ -440,7 +440,7 @@ public static class ExternalHttpClientTimeout
customChain.ChainPolicy.CustomTrustStore.AddRange(customRootCertificateCache.Certificates);
customChain.ChainPolicy.ApplicationPolicy.Add(new Oid(TLS_SERVER_AUTHENTICATION_EKU_OID));
// Match the .NET 9 HttpClient default used for the initial system-trust validation.
// Match the HttpClient default used for the initial system-trust validation, which .NET 10 kept.
// Hostname, signature, validity, EKU, and root trust checks remain enabled.
customChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
@@ -0,0 +1,41 @@
using System.Reflection;
namespace AIStudio.Tools.Metadata;
/// <summary>
/// The .NET runtime which runs the app.
/// </summary>
/// <remarks>
/// Asked while the app runs instead of taken from metadata.txt: a release brings its own runtime,
/// and a development build runs on whichever runtime the developer installed.
/// </remarks>
public static class DotnetRuntimeVersion
{
/// <summary>
/// How many characters of the commit we show, as metadata.txt does.
/// </summary>
private const int COMMIT_LENGTH = 10;
/// <summary>
/// Gets the version of the runtime together with the commit it was built from, such as
/// <c>10.0.14 (commit 0427b9abbe)</c>.
/// </summary>
public static string Current { get; } = Describe(Environment.Version, typeof(object).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion);
/// <summary>
/// Describes a version of the runtime together with the commit which the informational version
/// of its core library names after a plus sign, such as <c>10.0.14+0427b9abbead3f…</c>.
/// </summary>
/// <param name="version">The version of the runtime.</param>
/// <param name="informationalVersion">The informational version of the core library, if any.</param>
/// <returns>The version with its commit, or the version alone when the commit is unknown.</returns>
internal static string Describe(Version version, string? informationalVersion)
{
if (string.IsNullOrWhiteSpace(informationalVersion))
return version.ToString();
var plusIndex = informationalVersion.IndexOf('+');
var commit = plusIndex < 0 ? string.Empty : informationalVersion[(plusIndex + 1)..];
return commit.Length < COMMIT_LENGTH ? version.ToString() : $"{version} (commit {commit[..COMMIT_LENGTH]})";
}
}
@@ -7,7 +7,6 @@ public class MetaDataAttribute(
string buildTime,
uint buildNum,
string dotnetSdkVersion,
string dotnetVersion,
string rustVersion,
string mudBlazorVersion,
string tauriVersion,
@@ -20,8 +19,9 @@ public class MetaDataAttribute(
public uint BuildNum => buildNum;
public string DotnetVersion => dotnetVersion;
/// <summary>
/// Gets the .NET SDK which built the app. The .NET runtime which runs it is <see cref="DotnetRuntimeVersion.Current"/>.
/// </summary>
public string DotnetSdkVersion => dotnetSdkVersion;
public string RustVersion => rustVersion;
@@ -549,12 +549,22 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM
}
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
public override Task StartAsync(CancellationToken cancellationToken)
{
// Changes to the embedding settings which do not pass through the queue, cf. ProcessMessage:
//
// Changes to the embedding settings which do not pass through the queue, cf. ProcessMessage.
// We listen for them while the app starts: since .NET 10, ExecuteAsync runs as a task of its
// own from its very first line, and a message sent before that task got its turn would go
// unnoticed.
//
MessageBus.INSTANCE.RegisterComponent(this);
this.ApplyFilters([], [Event.PLUGINS_RELOADED, Event.CONFIGURATION_CHANGED]);
return base.StartAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await this.WaitForInitialSettingsAndBootstrapAsync(stoppingToken);
while (!stoppingToken.IsCancellationRequested)
@@ -27,12 +27,9 @@ public partial class RustService
// Read events line by line:
using var reader = new StreamReader(stream);
// Read until the end of the stream or cancellation:
while(!reader.EndOfStream && !stopToken.IsCancellationRequested)
// Read the next line of JSON until the end of the stream or cancellation:
while(!stopToken.IsCancellationRequested && await reader.ReadLineAsync(stopToken) is { } line)
{
// Read the next line of JSON from the stream:
var line = await reader.ReadLineAsync(stopToken);
// Skip empty lines:
if (string.IsNullOrWhiteSpace(line))
continue;
@@ -352,9 +352,8 @@ public sealed partial class RustService
await using var stream = await response.Content.ReadAsStreamAsync(token);
using var reader = new StreamReader(stream);
while (!reader.EndOfStream && !token.IsCancellationRequested)
while (!token.IsCancellationRequested && await reader.ReadLineAsync(token) is { } line)
{
var line = await reader.ReadLineAsync(token);
if (string.IsNullOrWhiteSpace(line))
continue;