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:
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user