v1.16 — Remove PowerShell edition, restore flat project structure
PowerShell version removed — will use OV code signing certificate instead. Files moved back from src/ to project root. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
185
Services/LicenseManager.cs
Normal file
185
Services/LicenseManager.cs
Normal file
@@ -0,0 +1,185 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
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; }
|
||||
|
||||
public bool FindOspp()
|
||||
{
|
||||
var searchPaths = new[]
|
||||
{
|
||||
// Click-to-Run (leggyakoribb — Office 365, 2019, 2021, 2024)
|
||||
@"C:\Program Files\Microsoft Office\root\Office16\OSPP.VBS",
|
||||
@"C:\Program Files (x86)\Microsoft Office\root\Office16\OSPP.VBS",
|
||||
// Hagyományos MSI
|
||||
@"C:\Program Files\Microsoft Office\Office16\ospp.vbs",
|
||||
@"C:\Program Files (x86)\Microsoft Office\Office16\ospp.vbs",
|
||||
@"C:\Program Files\Microsoft Office\Office15\ospp.vbs",
|
||||
@"C:\Program Files (x86)\Microsoft Office\Office15\ospp.vbs",
|
||||
@"C:\Program Files\Microsoft Office\Office14\ospp.vbs",
|
||||
@"C:\Program Files (x86)\Microsoft Office\Office14\ospp.vbs",
|
||||
};
|
||||
|
||||
foreach (var path in searchPaths)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
OsppPath = path;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var c2rPath = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
|
||||
@"SOFTWARE\Microsoft\Office\ClickToRun\Configuration")
|
||||
?.GetValue("InstallationPath") as string;
|
||||
|
||||
if (!string.IsNullOrEmpty(c2rPath))
|
||||
{
|
||||
// C2R: root\Office16 vagy sima Office16
|
||||
var candidates = new[]
|
||||
{
|
||||
Path.Combine(c2rPath, "root", "Office16", "OSPP.VBS"),
|
||||
Path.Combine(c2rPath, "Office16", "OSPP.VBS"),
|
||||
};
|
||||
foreach (var candidate in candidates)
|
||||
{
|
||||
if (File.Exists(candidate))
|
||||
{
|
||||
OsppPath = candidate;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task<string> GetStatusAsync()
|
||||
{
|
||||
if (string.IsNullOrEmpty(OsppPath))
|
||||
return "Az ospp.vbs nem tal\u00e1lhat\u00f3.";
|
||||
|
||||
var runner = new ProcessRunner();
|
||||
return await runner.RunAndCaptureAsync("cscript",
|
||||
"//Nologo \"" + OsppPath + "\" /dstatus");
|
||||
}
|
||||
|
||||
public List<string> ParseLicenseKeys(string dstatusOutput)
|
||||
{
|
||||
var keys = new List<string>();
|
||||
var regex = new Regex(@"Last 5 characters of installed product key:\s*(\S+)",
|
||||
RegexOptions.IgnoreCase);
|
||||
|
||||
foreach (Match match in regex.Matches(dstatusOutput))
|
||||
{
|
||||
keys.Add(match.Groups[1].Value);
|
||||
}
|
||||
|
||||
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))
|
||||
return "Az ospp.vbs nem tal\u00e1lhat\u00f3.";
|
||||
|
||||
var runner = new ProcessRunner();
|
||||
return await runner.RunAndCaptureAsync("cscript",
|
||||
"//Nologo \"" + OsppPath + "\" /unpkey:" + last5Chars);
|
||||
}
|
||||
|
||||
public async Task<string> RemoveAllKeysAsync()
|
||||
{
|
||||
var status = await GetStatusAsync();
|
||||
var keys = ParseLicenseKeys(status);
|
||||
|
||||
if (keys.Count == 0)
|
||||
return "Nem tal\u00e1lhat\u00f3 telep\u00edtett term\u00e9kkulcs.";
|
||||
|
||||
var results = new List<string>();
|
||||
foreach (var key in keys)
|
||||
{
|
||||
var result = await RemoveKeyAsync(key);
|
||||
results.Add(key + ": " + result.Trim());
|
||||
}
|
||||
|
||||
return string.Join("\n", results);
|
||||
}
|
||||
|
||||
public async Task<string> InstallKeyAsync(string productKey)
|
||||
{
|
||||
if (string.IsNullOrEmpty(OsppPath))
|
||||
return "Az ospp.vbs nem tal\u00e1lhat\u00f3.";
|
||||
|
||||
var runner = new ProcessRunner();
|
||||
return await runner.RunAndCaptureAsync("cscript",
|
||||
"//Nologo \"" + OsppPath + "\" /inpkey:" + productKey);
|
||||
}
|
||||
|
||||
public async Task<string> ActivateAsync()
|
||||
{
|
||||
if (string.IsNullOrEmpty(OsppPath))
|
||||
return "Az ospp.vbs nem tal\u00e1lhat\u00f3.";
|
||||
|
||||
var runner = new ProcessRunner();
|
||||
return await runner.RunAndCaptureAsync("cscript",
|
||||
"//Nologo \"" + OsppPath + "\" /act");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user