v1.02 — License troubleshoot UI improvements

- Fix ospp.vbs path: add root\Office16 for Click-to-Run installs
- Individual key cards with per-key remove buttons
- "Remove all" only shown when 2+ keys found
- Collapsible "Details" section (ospp.vbs path + raw output)
- All log/output fields now selectable and copyable (TextBox)
- Parse license entries (name, status, error, key) from dstatus output

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hariel1985
2026-03-31 05:51:26 +02:00
szülő 4937ac4b1c
commit e8abb03eee
5 fájl változott, egészen pontosan 264 új sor hozzáadva és 54 régi sor törölve

Fájl megtekintése

@@ -6,6 +6,15 @@ using System.Threading.Tasks;
namespace InstaSoftOfficeTool.Services
{
public class LicenseEntry
{
public string LicenseName { get; set; } = "";
public string Description { get; set; } = "";
public string Status { get; set; } = "";
public string ErrorDescription { get; set; } = "";
public string Last5 { get; set; } = "";
}
public class LicenseManager
{
public string OsppPath { get; private set; }
@@ -88,6 +97,43 @@ namespace InstaSoftOfficeTool.Services
return keys;
}
public List<LicenseEntry> ParseLicenseEntries(string dstatusOutput)
{
var entries = new List<LicenseEntry>();
// Split by "-------" separator blocks
var blocks = Regex.Split(dstatusOutput, @"-{10,}");
foreach (var block in blocks)
{
var trimmed = block.Trim();
if (string.IsNullOrEmpty(trimmed)) continue;
if (trimmed.StartsWith("---Processing") || trimmed.StartsWith("---Exiting")) continue;
var entry = new LicenseEntry();
var nameMatch = Regex.Match(trimmed, @"LICENSE NAME:\s*(.+)", RegexOptions.IgnoreCase);
if (nameMatch.Success) entry.LicenseName = nameMatch.Groups[1].Value.Trim();
var descMatch = Regex.Match(trimmed, @"LICENSE DESCRIPTION:\s*(.+)", RegexOptions.IgnoreCase);
if (descMatch.Success) entry.Description = descMatch.Groups[1].Value.Trim();
var statusMatch = Regex.Match(trimmed, @"LICENSE STATUS:\s*(.+)", RegexOptions.IgnoreCase);
if (statusMatch.Success) entry.Status = statusMatch.Groups[1].Value.Trim();
var errorMatch = Regex.Match(trimmed, @"ERROR DESCRIPTION:\s*(.+)", RegexOptions.IgnoreCase);
if (errorMatch.Success) entry.ErrorDescription = errorMatch.Groups[1].Value.Trim();
var keyMatch = Regex.Match(trimmed, @"Last 5 characters of installed product key:\s*(\S+)", RegexOptions.IgnoreCase);
if (keyMatch.Success) entry.Last5 = keyMatch.Groups[1].Value.Trim();
if (!string.IsNullOrEmpty(entry.Last5))
entries.Add(entry);
}
return entries;
}
public async Task<string> RemoveKeyAsync(string last5Chars)
{
if (string.IsNullOrEmpty(OsppPath))