mirror of
https://github.com/wwiinnddyy/LanMountainDesktop.git
synced 2026-06-22 00:54:26 +08:00
fix.正在修复 .NET运行时问题
This commit is contained in:
74
LanMountainDesktop.Tests/AirAppProcessStarterRuntimeTests.cs
Normal file
74
LanMountainDesktop.Tests/AirAppProcessStarterRuntimeTests.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using LanMountainDesktop.Launcher.Services;
|
||||
using LanMountainDesktop.Launcher.Services.AirApp;
|
||||
using Xunit;
|
||||
|
||||
namespace LanMountainDesktop.Tests;
|
||||
|
||||
public sealed class AirAppProcessStarterRuntimeTests : IDisposable
|
||||
{
|
||||
private readonly string _root;
|
||||
|
||||
public AirAppProcessStarterRuntimeTests()
|
||||
{
|
||||
_root = Path.Combine(Path.GetTempPath(), "LanMountainDesktop.AirAppProcessStarterRuntimeTests", Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(_root);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateStartInfo_UsesPackagedExecutable_WhenExeExists()
|
||||
{
|
||||
var hostPath = Path.Combine(_root, OperatingSystem.IsWindows()
|
||||
? "LanMountainDesktop.AirAppHost.exe"
|
||||
: "LanMountainDesktop.AirAppHost");
|
||||
File.WriteAllText(hostPath, string.Empty);
|
||||
|
||||
var startInfo = AirAppProcessStarter.CreateStartInfo(hostPath);
|
||||
|
||||
Assert.Equal(hostPath, startInfo.FileName);
|
||||
Assert.Empty(startInfo.ArgumentList);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateStartInfo_UsesArchitectureMatchedDotnetHost_ForDllFallbackOnWindows()
|
||||
{
|
||||
if (!OperatingSystem.IsWindows())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var programFiles = Path.Combine(_root, "ProgramFiles");
|
||||
var dotnetRoot = Path.Combine(programFiles, "dotnet");
|
||||
Directory.CreateDirectory(dotnetRoot);
|
||||
var dotnetHost = Path.Combine(dotnetRoot, "dotnet.exe");
|
||||
File.WriteAllText(dotnetHost, string.Empty);
|
||||
Directory.CreateDirectory(Path.Combine(
|
||||
dotnetRoot,
|
||||
"shared",
|
||||
DotNetRuntimeProbe.RequiredSharedFrameworkName,
|
||||
"10.0.5"));
|
||||
|
||||
var hostDll = Path.Combine(_root, "LanMountainDesktop.AirAppHost.dll");
|
||||
File.WriteAllText(hostDll, string.Empty);
|
||||
var options = new DotNetRuntimeProbeOptions
|
||||
{
|
||||
Architecture = DotNetRuntimeArchitecture.X64,
|
||||
ProgramFilesPath = programFiles,
|
||||
ProgramFilesX86Path = Path.Combine(_root, "ProgramFilesX86"),
|
||||
IncludeRegistry = false,
|
||||
IncludeDotNetCli = false
|
||||
};
|
||||
|
||||
var startInfo = AirAppProcessStarter.CreateStartInfo(hostDll, options);
|
||||
|
||||
Assert.Equal(dotnetHost, startInfo.FileName);
|
||||
Assert.Equal(hostDll, startInfo.ArgumentList.Single());
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Directory.Exists(_root))
|
||||
{
|
||||
Directory.Delete(_root, recursive: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
135
LanMountainDesktop.Tests/DotNetRuntimeProbeTests.cs
Normal file
135
LanMountainDesktop.Tests/DotNetRuntimeProbeTests.cs
Normal file
@@ -0,0 +1,135 @@
|
||||
using LanMountainDesktop.Launcher.Services;
|
||||
using Xunit;
|
||||
|
||||
namespace LanMountainDesktop.Tests;
|
||||
|
||||
public sealed class DotNetRuntimeProbeTests : IDisposable
|
||||
{
|
||||
private readonly string _root;
|
||||
private readonly string _programFiles;
|
||||
private readonly string _programFilesX86;
|
||||
|
||||
public DotNetRuntimeProbeTests()
|
||||
{
|
||||
_root = Path.Combine(Path.GetTempPath(), "LanMountainDesktop.DotNetRuntimeProbeTests", Guid.NewGuid().ToString("N"));
|
||||
_programFiles = Path.Combine(_root, "ProgramFiles");
|
||||
_programFilesX86 = Path.Combine(_root, "ProgramFilesX86");
|
||||
Directory.CreateDirectory(_programFiles);
|
||||
Directory.CreateDirectory(_programFilesX86);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Probe_AcceptsTargetArchitectureRuntime_WhenDotnetHostIsMissing()
|
||||
{
|
||||
CreateRuntime(_programFiles, "10.0.5");
|
||||
|
||||
var result = DotNetRuntimeProbe.Probe(CreateOptions(DotNetRuntimeArchitecture.X64));
|
||||
|
||||
Assert.True(result.IsAvailable);
|
||||
Assert.Null(result.DotNetHostPath);
|
||||
Assert.Contains(result.DetectedRuntimes, runtime => runtime.Version == "10.0.5");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Probe_X64DoesNotAcceptX86OnlyRuntime()
|
||||
{
|
||||
CreateRuntime(_programFilesX86, "10.0.5");
|
||||
|
||||
var result = DotNetRuntimeProbe.Probe(CreateOptions(DotNetRuntimeArchitecture.X64));
|
||||
|
||||
Assert.False(result.IsAvailable);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Probe_X86DoesNotAcceptX64OnlyRuntime()
|
||||
{
|
||||
CreateRuntime(_programFiles, "10.0.5");
|
||||
|
||||
var result = DotNetRuntimeProbe.Probe(CreateOptions(DotNetRuntimeArchitecture.X86));
|
||||
|
||||
Assert.False(result.IsAvailable);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Probe_RejectsOlderMajorVersions()
|
||||
{
|
||||
CreateRuntime(_programFiles, "8.0.25");
|
||||
CreateRuntime(_programFiles, "9.0.14");
|
||||
|
||||
var result = DotNetRuntimeProbe.Probe(CreateOptions(DotNetRuntimeArchitecture.X64));
|
||||
|
||||
Assert.False(result.IsAvailable);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ValidateDotNetRuntimePrerequisite_ReturnsStructuredFailure_WhenRuntimeIsMissing()
|
||||
{
|
||||
if (!OperatingSystem.IsWindows())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var appDir = Path.Combine(_root, "app-1.0.0");
|
||||
Directory.CreateDirectory(appDir);
|
||||
var hostPath = Path.Combine(appDir, "LanMountainDesktop.exe");
|
||||
File.WriteAllText(hostPath, string.Empty);
|
||||
File.WriteAllText(Path.Combine(appDir, "LanMountainDesktop.runtimeconfig.json"), "{}");
|
||||
|
||||
var plan = new HostLaunchPlan(
|
||||
hostPath,
|
||||
_root,
|
||||
appDir,
|
||||
[],
|
||||
new Dictionary<string, string>(),
|
||||
new() { Version = "1.0.0", Codename = "Test" });
|
||||
var resolution = new HostResolutionResult
|
||||
{
|
||||
Success = true,
|
||||
ResolvedHostPath = hostPath,
|
||||
AppRoot = _root,
|
||||
ResolutionSource = "test",
|
||||
SearchedPaths = [hostPath]
|
||||
};
|
||||
|
||||
var result = LauncherFlowCoordinator.ValidateDotNetRuntimePrerequisite(
|
||||
plan,
|
||||
resolution,
|
||||
CreateOptions(DotNetRuntimeArchitecture.X64));
|
||||
|
||||
Assert.NotNull(result);
|
||||
Assert.False(result.Success);
|
||||
Assert.Equal("dotnet_runtime_missing", result.Code);
|
||||
Assert.Equal("False", result.Details["dotnetRuntimeAvailable"]);
|
||||
}
|
||||
|
||||
private DotNetRuntimeProbeOptions CreateOptions(DotNetRuntimeArchitecture architecture)
|
||||
{
|
||||
return new DotNetRuntimeProbeOptions
|
||||
{
|
||||
Architecture = architecture,
|
||||
ProgramFilesPath = _programFiles,
|
||||
ProgramFilesX86Path = _programFilesX86,
|
||||
DotNetHostCandidates = [],
|
||||
IncludeRegistry = false,
|
||||
IncludeDotNetCli = false
|
||||
};
|
||||
}
|
||||
|
||||
private static void CreateRuntime(string programFilesRoot, string version)
|
||||
{
|
||||
Directory.CreateDirectory(Path.Combine(
|
||||
programFilesRoot,
|
||||
"dotnet",
|
||||
"shared",
|
||||
DotNetRuntimeProbe.RequiredSharedFrameworkName,
|
||||
version));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Directory.Exists(_root))
|
||||
{
|
||||
Directory.Delete(_root, recursive: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
57
LanMountainDesktop.Tests/PackagingRuntimePolicyTests.cs
Normal file
57
LanMountainDesktop.Tests/PackagingRuntimePolicyTests.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using Xunit;
|
||||
|
||||
namespace LanMountainDesktop.Tests;
|
||||
|
||||
public sealed class PackagingRuntimePolicyTests
|
||||
{
|
||||
[Fact]
|
||||
public void WindowsPackageScript_PublishesLauncherRootAndFrameworkDependentAppDirectory()
|
||||
{
|
||||
var script = ReadRepositoryFile("LanMountainDesktop", "scripts", "package.ps1");
|
||||
|
||||
Assert.Contains("Publish-LauncherPayload", script);
|
||||
Assert.Contains("\"app-$Version\"", script);
|
||||
Assert.Contains("Publish-MainAppFrameworkDependentPayload", script);
|
||||
Assert.Contains("\"--self-contained\", \"false\"", script);
|
||||
Assert.Contains("\"-p:SelfContained=false\"", script);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WindowsPayloadGuard_BlocksBundledDotNetRuntimeFiles()
|
||||
{
|
||||
var script = ReadRepositoryFile("LanMountainDesktop", "scripts", "Optimize-PublishPayload.ps1");
|
||||
|
||||
Assert.Contains("coreclr.dll", script);
|
||||
Assert.Contains("hostfxr.dll", script);
|
||||
Assert.Contains("hostpolicy.dll", script);
|
||||
Assert.Contains("System.Private.CoreLib.dll", script);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Installer_DownloadsArchitectureSpecificDesktopRuntime()
|
||||
{
|
||||
var installer = ReadRepositoryFile("LanMountainDesktop", "installer", "LanMountainDesktop.iss");
|
||||
|
||||
Assert.Contains("https://aka.ms/dotnet/10.0/windowsdesktop-runtime-win-x64.exe", installer);
|
||||
Assert.Contains("https://aka.ms/dotnet/10.0/windowsdesktop-runtime-win-x86.exe", installer);
|
||||
Assert.Contains("/install /quiet /norestart", installer);
|
||||
Assert.Contains("ExitCode <> 3010", installer);
|
||||
Assert.DoesNotContain("IsSelfContainedBuild", installer);
|
||||
}
|
||||
|
||||
private static string ReadRepositoryFile(params string[] pathParts)
|
||||
{
|
||||
var directory = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
while (directory is not null && !File.Exists(Path.Combine(directory.FullName, "LanMountainDesktop.slnx")))
|
||||
{
|
||||
directory = directory.Parent;
|
||||
}
|
||||
|
||||
if (directory is null)
|
||||
{
|
||||
throw new DirectoryNotFoundException("Unable to locate repository root.");
|
||||
}
|
||||
|
||||
return File.ReadAllText(Path.Combine([directory.FullName, .. pathParts]));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user