Fix Java 8 resolution for MfApi restart, refresh targets after settings, and copy errors to clipboard.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
namespace ZA.CoreService.ESBCertificateManager.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Fehlerdialog mit Text und Button „In Zwischenablage kopieren“.
|
||||
/// Kopiert den Fehlertext beim Öffnen automatisch.
|
||||
/// </summary>
|
||||
public static class CopyableErrorDialog
|
||||
{
|
||||
public static void Show(
|
||||
IWin32Window? owner,
|
||||
string title,
|
||||
string details)
|
||||
{
|
||||
string text = string.IsNullOrWhiteSpace(details)
|
||||
? "(keine Fehlerdetails)"
|
||||
: details.Trim();
|
||||
|
||||
TryCopy(text);
|
||||
|
||||
using Form dialog = new()
|
||||
{
|
||||
Text = title,
|
||||
StartPosition = FormStartPosition.CenterParent,
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog,
|
||||
MaximizeBox = false,
|
||||
MinimizeBox = false,
|
||||
ShowInTaskbar = false,
|
||||
ClientSize = new Size(640, 420),
|
||||
BackColor = Color.FromArgb(16, 28, 48),
|
||||
ForeColor = Color.FromArgb(241, 245, 249),
|
||||
Font = new Font("Segoe UI", 9.5f)
|
||||
};
|
||||
|
||||
Label hint = new()
|
||||
{
|
||||
Text =
|
||||
"Fehlertext ist in der Zwischenablage — "
|
||||
+ "einfach hier einfügen (Strg+V).",
|
||||
Location = new Point(16, 12),
|
||||
AutoSize = false,
|
||||
Size = new Size(608, 28),
|
||||
ForeColor = Color.FromArgb(208, 171, 57)
|
||||
};
|
||||
|
||||
TextBox box = new()
|
||||
{
|
||||
Location = new Point(16, 44),
|
||||
Size = new Size(608, 310),
|
||||
Multiline = true,
|
||||
ReadOnly = true,
|
||||
ScrollBars = ScrollBars.Both,
|
||||
WordWrap = false,
|
||||
Text = text,
|
||||
BackColor = Color.FromArgb(12, 22, 38),
|
||||
ForeColor = Color.FromArgb(241, 245, 249),
|
||||
BorderStyle = BorderStyle.FixedSingle,
|
||||
Font = new Font("Consolas", 9f)
|
||||
};
|
||||
|
||||
Label copyStatus = new()
|
||||
{
|
||||
Text = "✓ In Zwischenablage kopiert",
|
||||
Location = new Point(16, 368),
|
||||
AutoSize = true,
|
||||
ForeColor = Color.FromArgb(90, 200, 140)
|
||||
};
|
||||
|
||||
Button btnCopy = new()
|
||||
{
|
||||
Text = "Nochmal kopieren",
|
||||
Location = new Point(280, 362),
|
||||
Size = new Size(160, 36),
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
BackColor = Color.FromArgb(39, 52, 73),
|
||||
ForeColor = Color.FromArgb(241, 245, 249),
|
||||
Cursor = Cursors.Hand
|
||||
};
|
||||
|
||||
btnCopy.FlatAppearance.BorderColor =
|
||||
Color.FromArgb(36, 74, 117);
|
||||
|
||||
btnCopy.Click += (_, _) =>
|
||||
{
|
||||
if (TryCopy(text))
|
||||
{
|
||||
copyStatus.Text = "✓ Erneut kopiert";
|
||||
copyStatus.ForeColor =
|
||||
Color.FromArgb(90, 200, 140);
|
||||
}
|
||||
else
|
||||
{
|
||||
copyStatus.Text = "Kopieren fehlgeschlagen";
|
||||
copyStatus.ForeColor =
|
||||
Color.FromArgb(220, 100, 100);
|
||||
}
|
||||
};
|
||||
|
||||
Button btnClose = new()
|
||||
{
|
||||
Text = "Schließen",
|
||||
Location = new Point(456, 362),
|
||||
Size = new Size(168, 36),
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
BackColor = Color.FromArgb(0, 110, 182),
|
||||
ForeColor = Color.White,
|
||||
Cursor = Cursors.Hand,
|
||||
DialogResult = DialogResult.OK
|
||||
};
|
||||
|
||||
btnClose.FlatAppearance.BorderSize = 0;
|
||||
|
||||
dialog.Controls.Add(hint);
|
||||
dialog.Controls.Add(box);
|
||||
dialog.Controls.Add(copyStatus);
|
||||
dialog.Controls.Add(btnCopy);
|
||||
dialog.Controls.Add(btnClose);
|
||||
dialog.AcceptButton = btnClose;
|
||||
dialog.CancelButton = btnClose;
|
||||
|
||||
dialog.ShowDialog(owner);
|
||||
}
|
||||
|
||||
private static bool TryCopy(string text)
|
||||
{
|
||||
try
|
||||
{
|
||||
Clipboard.SetText(text);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
namespace ZA.CoreService.ESBCertificateManager.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Findet eine nutzbare Java-8-Runtime für Sonic MfApi.
|
||||
/// </summary>
|
||||
public static class JavaRuntimeLocator
|
||||
{
|
||||
public static string? Resolve(
|
||||
string? configuredPath = null)
|
||||
{
|
||||
foreach (string? candidate in EnumerateCandidates(configuredPath))
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(candidate))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string? resolved = TryResolveExisting(candidate);
|
||||
|
||||
if (resolved is not null)
|
||||
{
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static IEnumerable<string?> EnumerateCandidates(
|
||||
string? configuredPath)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(configuredPath))
|
||||
{
|
||||
yield return configuredPath.Trim();
|
||||
}
|
||||
|
||||
yield return
|
||||
@"C:\Program Files (x86)\Java\jre1.8.0_481\bin\java.exe";
|
||||
|
||||
yield return
|
||||
@"C:\Program Files (x86)\Java\jre1.8.0_501\bin\java.exe";
|
||||
|
||||
yield return
|
||||
@"C:\Program Files\Java\jre1.8.0_481\bin\java.exe";
|
||||
|
||||
yield return
|
||||
@"C:\Program Files (x86)\Common Files\Oracle\Java\java8path\java.exe";
|
||||
|
||||
foreach (string root in new[]
|
||||
{
|
||||
@"C:\Program Files (x86)\Java",
|
||||
@"C:\Program Files\Java"
|
||||
})
|
||||
{
|
||||
if (!Directory.Exists(root))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (string directory in Directory
|
||||
.EnumerateDirectories(root, "jre1.8*")
|
||||
.OrderByDescending(path => path, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
yield return Path.Combine(directory, "bin", "java.exe");
|
||||
}
|
||||
|
||||
foreach (string directory in Directory
|
||||
.EnumerateDirectories(root, "jdk1.8*")
|
||||
.OrderByDescending(path => path, StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
yield return Path.Combine(directory, "bin", "java.exe");
|
||||
}
|
||||
}
|
||||
|
||||
string? javaHome =
|
||||
Environment.GetEnvironmentVariable("JAVA_HOME");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(javaHome))
|
||||
{
|
||||
yield return Path.Combine(
|
||||
javaHome.Trim(),
|
||||
"bin",
|
||||
"java.exe");
|
||||
}
|
||||
|
||||
string? jreHome =
|
||||
Environment.GetEnvironmentVariable("JRE_HOME");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(jreHome))
|
||||
{
|
||||
yield return Path.Combine(
|
||||
jreHome.Trim(),
|
||||
"bin",
|
||||
"java.exe");
|
||||
}
|
||||
|
||||
yield return "java.exe";
|
||||
}
|
||||
|
||||
private static string? TryResolveExisting(string candidate)
|
||||
{
|
||||
try
|
||||
{
|
||||
string resolved =
|
||||
Path.IsPathRooted(candidate)
|
||||
? Path.GetFullPath(candidate)
|
||||
: Path.GetFullPath(
|
||||
Path.Combine(
|
||||
AppContext.BaseDirectory,
|
||||
candidate));
|
||||
|
||||
return File.Exists(resolved)
|
||||
? resolved
|
||||
: null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,9 @@ public sealed class RestartExecutor
|
||||
if (connection is null)
|
||||
{
|
||||
return (false, "Sonic-Verbindung nicht gefunden",
|
||||
$"Ziel '{target.Name}': SonicConnection '{target.SonicConnectionName}' fehlt in appsettings.");
|
||||
$"Ziel '{target.Name}': SonicConnection '{target.SonicConnectionName}' "
|
||||
+ "ist nicht geladen. Meist fehlt ein Benutzerprofil "
|
||||
+ "(Einstellungen → Profil anlegen und übernehmen).");
|
||||
}
|
||||
|
||||
using SonicManagementClient client =
|
||||
|
||||
@@ -11,8 +11,8 @@ public sealed class RuntimeEnvironmentValidator
|
||||
{
|
||||
List<string> issues = [];
|
||||
|
||||
string javaExecutablePath =
|
||||
PathResolver.ResolvePath(
|
||||
string? javaExecutablePath =
|
||||
JavaRuntimeLocator.Resolve(
|
||||
settings.JavaExecutablePath);
|
||||
|
||||
string sonicClientLibraryPath =
|
||||
@@ -21,10 +21,11 @@ public sealed class RuntimeEnvironmentValidator
|
||||
|
||||
string javaVersion = string.Empty;
|
||||
|
||||
if (!File.Exists(javaExecutablePath))
|
||||
if (javaExecutablePath is null)
|
||||
{
|
||||
issues.Add(
|
||||
$"Java wurde nicht gefunden: {javaExecutablePath}");
|
||||
"Java 8 wurde nicht gefunden. "
|
||||
+ "Runtime:JavaExecutablePath oder installierte jre1.8* prüfen.");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -80,7 +81,7 @@ public sealed class RuntimeEnvironmentValidator
|
||||
return new RuntimeValidationResult
|
||||
{
|
||||
IsValid = issues.Count == 0,
|
||||
JavaExecutablePath = javaExecutablePath,
|
||||
JavaExecutablePath = javaExecutablePath ?? string.Empty,
|
||||
SonicClientLibraryPath = sonicClientLibraryPath,
|
||||
JavaVersion = javaVersion,
|
||||
Issues = issues
|
||||
|
||||
@@ -44,8 +44,8 @@ public sealed class SonicCredentialTester
|
||||
"Für den Verbindungstest fehlt ein Container.");
|
||||
}
|
||||
|
||||
string javaPath =
|
||||
PathResolver.ResolvePath(
|
||||
string? javaPath =
|
||||
JavaRuntimeLocator.Resolve(
|
||||
_runtimeSettings.JavaExecutablePath);
|
||||
|
||||
string libraryPath =
|
||||
@@ -55,10 +55,12 @@ public sealed class SonicCredentialTester
|
||||
string? toolsPath =
|
||||
ResolveToolsDirectory();
|
||||
|
||||
if (!File.Exists(javaPath))
|
||||
if (javaPath is null)
|
||||
{
|
||||
return CredentialTestResult.Failed(
|
||||
$"Java wurde nicht gefunden: {javaPath}");
|
||||
"Java 8 wurde nicht gefunden. "
|
||||
+ "Runtime:JavaExecutablePath prüfen "
|
||||
+ @"(z. B. C:\Program Files (x86)\Java\jre1.8.0_481\bin\java.exe).");
|
||||
}
|
||||
|
||||
if (!Directory.Exists(libraryPath))
|
||||
|
||||
@@ -356,84 +356,35 @@ public sealed class SonicMfApiExecutor
|
||||
|
||||
private string? ResolveJavaExe()
|
||||
{
|
||||
foreach (string? candidate
|
||||
in EnumerateJavaCandidates())
|
||||
// Explizite Verbindungs-Pfade zuerst, dann Java-8-Suche
|
||||
// (Runtime\bin\java.exe fehlt oft; JAVA_HOME zeigt oft auf JDK 21).
|
||||
string? fromConnection = JavaRuntimeLocator.Resolve(
|
||||
!string.IsNullOrWhiteSpace(_connection.JavaPath)
|
||||
? _connection.JavaPath
|
||||
: null);
|
||||
|
||||
if (fromConnection is not null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(candidate))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string resolvedCandidate;
|
||||
|
||||
try
|
||||
{
|
||||
resolvedCandidate =
|
||||
Path.IsPathRooted(candidate)
|
||||
? Path.GetFullPath(candidate)
|
||||
: Path.GetFullPath(
|
||||
Path.Combine(
|
||||
AppContext.BaseDirectory,
|
||||
candidate));
|
||||
}
|
||||
catch
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (File.Exists(resolvedCandidate))
|
||||
{
|
||||
return resolvedCandidate;
|
||||
}
|
||||
return fromConnection;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private IEnumerable<string?>
|
||||
EnumerateJavaCandidates()
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(
|
||||
_connection.JavaPath))
|
||||
if (!string.IsNullOrWhiteSpace(_connection.JavaHome))
|
||||
{
|
||||
yield return
|
||||
_connection.JavaPath.Trim();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(
|
||||
_connection.JavaHome))
|
||||
{
|
||||
yield return Path.Combine(
|
||||
string fromHome = Path.Combine(
|
||||
_connection.JavaHome.Trim(),
|
||||
"bin",
|
||||
"java.exe");
|
||||
|
||||
string? resolvedHome =
|
||||
JavaRuntimeLocator.Resolve(fromHome);
|
||||
|
||||
if (resolvedHome is not null)
|
||||
{
|
||||
return resolvedHome;
|
||||
}
|
||||
}
|
||||
|
||||
string? javaHome =
|
||||
Environment.GetEnvironmentVariable(
|
||||
"JAVA_HOME");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(javaHome))
|
||||
{
|
||||
yield return Path.Combine(
|
||||
javaHome.Trim(),
|
||||
"bin",
|
||||
"java.exe");
|
||||
}
|
||||
|
||||
string? jreHome =
|
||||
Environment.GetEnvironmentVariable(
|
||||
"JRE_HOME");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(jreHome))
|
||||
{
|
||||
yield return Path.Combine(
|
||||
jreHome.Trim(),
|
||||
"bin",
|
||||
"java.exe");
|
||||
}
|
||||
|
||||
yield return "java.exe";
|
||||
return JavaRuntimeLocator.Resolve();
|
||||
}
|
||||
|
||||
private (
|
||||
|
||||
Reference in New Issue
Block a user