.net check

This commit is contained in:
Dimitrij
2025-08-31 01:12:03 +01:00
parent fe3fb46e94
commit 30b674f8f5
3 changed files with 123 additions and 28 deletions

View File

@@ -5,8 +5,8 @@
<NoWarn>$(NoWarn);NU1507</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="AWSSDK.Core" Version="4.0.0.25" />
<PackageVersion Include="AWSSDK.EC2" Version="4.0.33" />
<PackageVersion Include="AWSSDK.Core" Version="4.0.0.26" />
<PackageVersion Include="AWSSDK.EC2" Version="4.0.35" />
<PackageVersion Include="BouncyCastle.Cryptography" Version="2.6.2" />
<PackageVersion Include="Castle.Core" Version="5.2.1" />
<PackageVersion Include="ConsoleControl" Version="1.3.0" />

View File

@@ -1,14 +1,20 @@
using System;
using mRemoteNG.Config.Settings;
using mRemoteNG.DotNet.Update;
using mRemoteNG.UI.Forms;
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading;
using System.Windows.Forms;
using mRemoteNG.Config.Settings;
using mRemoteNG.UI.Forms;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using mRemoteNG.DotNet.Update;
namespace mRemoteNG.App
{
@@ -25,13 +31,48 @@ namespace mRemoteNG.App
[STAThread]
public static void Main(string[] args)
{
Trace.WriteLine("!!!!!!=============== TEST ==================!!!!!!!!!!!!!");
// Forcing to load System.Configuration.ConfigurationManager before any other assembly to be able to check settings
try
{
string assemblyFile = "System.Configuration.ConfigurationManager" + ".dll";
string assemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assemblies", assemblyFile);
// FIX: Awaited Task<bool> synchronously to obtain bool result
bool isInstalled = DotNetRuntimeCheck
.IsDotnetRuntimeInstalled(DotNetRuntimeCheck.RequiredDotnetVersion)
.GetAwaiter()
.GetResult();
if (!isInstalled)
{
Trace.WriteLine($".NET Desktop Runtime {DotNetRuntimeCheck.RequiredDotnetVersion} is NOT installed.");
Trace.WriteLine("Please download and install it from:");
Trace.WriteLine("https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-9.0.8-windows-x64-installer");
try
{
MessageBox.Show(
$".NET Desktop Runtime {DotNetRuntimeCheck.RequiredDotnetVersion} is required.\n" +
"The application will now exit.\n\nDownload:\nhttps://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-9.0.8-windows-x64-installer",
"Missing .NET Runtime",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
} catch {
// Ignore UI issues
}
Environment.Exit(1);
return;
}
Trace.WriteLine($".NET Desktop Runtime {DotNetRuntimeCheck.RequiredDotnetVersion} is installed.");
} catch (Exception ex) {
Trace.WriteLine("Runtime check failed: " + ex);
Environment.Exit(1);
return;
}
Trace.WriteLine("!!!!!!=============== TEST ==================!!!!!!!!!!!!!");
try
{
string assemblyFile = "System.Configuration.ConfigurationManager.dll";
string assemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assemblies", assemblyFile);
if (File.Exists(assemblyPath))
{
@@ -40,13 +81,11 @@ namespace mRemoteNG.App
}
catch (FileNotFoundException ex)
{
Trace.WriteLine("Error occured: " + ex.Message);
Trace.WriteLine("Error occured: " + ex.Message);
}
//Subscribe to AssemblyResolve event
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
//Check if needed runtime is installed
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
string runtimeVersion = RuntimeInformation.FrameworkDescription;
@@ -66,12 +105,9 @@ namespace mRemoteNG.App
Console.WriteLine("This application requires the .NET Desktop Runtime 9.0.2 on Windows.");
}
//Check if local settings DB exist or accessible
CheckLockalDB();
Lazy<bool> singleInstanceOption = new Lazy<bool>(() => Properties.OptionsStartupExitPage.Default.SingleInstance);
Lazy<bool> singleInstanceOption = new(() => Properties.OptionsStartupExitPage.Default.SingleInstance);
if (singleInstanceOption.Value)
{
@@ -87,20 +123,20 @@ namespace mRemoteNG.App
{
LocalDBManager settingsManager = new LocalDBManager(dbPath: "mRemoteNG.appSettings", useEncryption: false, schemaFilePath: "");
}
private static Assembly OnAssemblyResolve(object sender, ResolveEventArgs resolveArgs)
{
string assemblyName = new AssemblyName(resolveArgs.Name).Name.Replace(".resources", string.Empty);
string assemblyFile = assemblyName + ".dll";
string assemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assemblies", assemblyFile);
if (File.Exists(assemblyPath))
{
return Assembly.LoadFrom(assemblyPath);
}
return null;
}
private static void StartApplication()
{
CatchAllUnhandledExceptions();
@@ -114,7 +150,6 @@ namespace mRemoteNG.App
Rectangle viewport = targetScreen.WorkingArea;
_frmSplashScreen.Top = viewport.Top;
_frmSplashScreen.Left = viewport.Left;
// normally it should be screens[1] however due DPI apply 1 size "same" as default with 100%
_frmSplashScreen.Left = viewport.Left + (targetScreen.Bounds.Size.Width - _frmSplashScreen.Width) / 2;
_frmSplashScreen.Top = viewport.Top + (targetScreen.Bounds.Size.Height - _frmSplashScreen.Height) / 2;
_frmSplashScreen.ShowInTaskbar = false;
@@ -168,14 +203,13 @@ namespace mRemoteNG.App
private static void CatchAllUnhandledExceptions()
{
System.Windows.Forms.Application.ThreadException += ApplicationOnThreadException;
System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.ThreadException += ApplicationOnThreadException;
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
}
private static void ApplicationOnThreadException(object sender, ThreadExceptionEventArgs e)
{
// if (PresentationSource.FromVisual(FrmSplashScreenNew))
FrmSplashScreenNew.GetInstance().Close();
if (FrmMain.Default.IsDisposed) return;
@@ -186,13 +220,8 @@ namespace mRemoteNG.App
private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
//TODO: Check if splash closed properly
//if (!FrmSplashScreenNew.GetInstance().IsDisposed)
// FrmSplashScreenNew.GetInstance().Close();
FrmUnhandledException window = new(e.ExceptionObject as Exception, e.IsTerminating);
window.ShowDialog(FrmMain.Default);
}
}
}

View File

@@ -0,0 +1,66 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace mRemoteNG.DotNet.Update
{
public class DotNetRuntimeCheck
{
public const string RequiredDotnetVersion = "9.0.8";
public const string DotnetInstallerUrl = "https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-9.0.8-windows-x64-installer";
public const string DotnetInstallerFileName = "windowsdesktop-runtime-9.0.8-win-x64.exe";
public static async Task Main(string[] args)
{
if (await IsDotnetRuntimeInstalled(RequiredDotnetVersion))
{
Console.WriteLine($".NET Desktop Runtime {RequiredDotnetVersion} is installed. Launching application...");
}
else
{
Console.WriteLine($".NET Desktop Runtime {RequiredDotnetVersion} is not installed.");
}
}
/// <summary>
/// Checks if a specific version of the .NET runtime is installed by running `dotnet --list-runtimes`.
/// </summary>
public static async Task<bool> IsDotnetRuntimeInstalled(string version)
{
try
{
// Set up a process to run the 'dotnet' command.
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "dotnet",
Arguments = "--list-runtimes",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
}
};
process.Start();
// Read the output from the command.
var output = await process.StandardOutput.ReadToEndAsync();
process.WaitForExit();
// Check if the output contains the required runtime and version.
// The format is typically: Microsoft.NETCore.App 9.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
return output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
.Any(line => line.Trim().StartsWith($"Microsoft.NETCore.App {version}") ||
line.Trim().StartsWith($"Microsoft.WindowsDesktop.App {version}"));
}
catch (Exception ex)
{
Console.WriteLine($"Could not check .NET runtimes. Please ensure 'dotnet' is in your PATH. Error: {ex.Message}");
return false;
}
}
} //Check
}