v1.15 — PowerShell edition + repo restructure
- New powershell/InstaSoftOfficeTool.ps1: single-file WPF GUI version - Same Fluent Design UI, no compilation needed - Runs on any Windows 7+ with PowerShell 5.1 (built-in) - Chrome won't flag .ps1 files as "rarely downloaded" - Auto-elevates to admin - Moved C# source to src/ subfolder - Updated .gitignore for nested bin/obj folders Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,116 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using InstaSoftOfficeTool.Models;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace InstaSoftOfficeTool.Services
|
||||
{
|
||||
public static class OfficeDetector
|
||||
{
|
||||
public static List<InstalledOffice> Detect()
|
||||
{
|
||||
var results = new List<InstalledOffice>();
|
||||
|
||||
// Check Click-to-Run
|
||||
DetectClickToRun(results);
|
||||
|
||||
// Check MSI-based installs
|
||||
DetectMsi(results);
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void DetectClickToRun(List<InstalledOffice> results)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var key = Registry.LocalMachine.OpenSubKey(
|
||||
@"SOFTWARE\Microsoft\Office\ClickToRun\Configuration"))
|
||||
{
|
||||
if (key == null) return;
|
||||
|
||||
var productIds = key.GetValue("ProductReleaseIds") as string;
|
||||
var versionToReport = key.GetValue("VersionToReport") as string;
|
||||
|
||||
if (string.IsNullOrEmpty(productIds)) return;
|
||||
|
||||
// Split into individual products (e.g. "O365BusinessRetail,VisioProRetail")
|
||||
var ids = productIds.Split(',');
|
||||
foreach (var id in ids)
|
||||
{
|
||||
var trimmedId = id.Trim();
|
||||
if (string.IsNullOrEmpty(trimmedId)) continue;
|
||||
|
||||
results.Add(new InstalledOffice
|
||||
{
|
||||
DisplayName = "Microsoft Office Click-to-Run (" + trimmedId + ")",
|
||||
Version = versionToReport ?? "",
|
||||
ProductCode = trimmedId,
|
||||
IsClickToRun = true,
|
||||
IsSelected = true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private static void DetectMsi(List<InstalledOffice> results)
|
||||
{
|
||||
var uninstallPaths = new[]
|
||||
{
|
||||
@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
|
||||
@"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
|
||||
};
|
||||
|
||||
foreach (var path in uninstallPaths)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var key = Registry.LocalMachine.OpenSubKey(path))
|
||||
{
|
||||
if (key == null) continue;
|
||||
|
||||
foreach (var subKeyName in key.GetSubKeyNames())
|
||||
{
|
||||
using (var subKey = key.OpenSubKey(subKeyName))
|
||||
{
|
||||
if (subKey == null) continue;
|
||||
|
||||
var displayName = subKey.GetValue("DisplayName") as string;
|
||||
var publisher = subKey.GetValue("Publisher") as string;
|
||||
|
||||
if (displayName != null &&
|
||||
publisher != null &&
|
||||
publisher.Contains("Microsoft") &&
|
||||
(displayName.Contains("Microsoft Office") ||
|
||||
displayName.Contains("Microsoft 365")))
|
||||
{
|
||||
var version = subKey.GetValue("DisplayVersion") as string ?? "";
|
||||
|
||||
// Skip Click-to-Run updater entries
|
||||
if (displayName.Contains("Click-to-Run") &&
|
||||
!displayName.Contains("Microsoft Office"))
|
||||
continue;
|
||||
|
||||
// Only accept {GUID} product codes for MSI uninstall
|
||||
bool isGuid = Regex.IsMatch(subKeyName, @"^\{[0-9A-Fa-f\-]+\}$");
|
||||
|
||||
results.Add(new InstalledOffice
|
||||
{
|
||||
DisplayName = displayName,
|
||||
Version = version,
|
||||
ProductCode = isGuid ? subKeyName : null,
|
||||
IsClickToRun = false,
|
||||
IsSelected = true
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user