diff --git a/InstaSoftOfficeTool.csproj b/InstaSoftOfficeTool.csproj
index 118726f..9b5d997 100644
--- a/InstaSoftOfficeTool.csproj
+++ b/InstaSoftOfficeTool.csproj
@@ -9,9 +9,9 @@
InstaSoft Zrt.
InstaSoft Office Tool
Copyright (c) InstaSoft Zrt. 2026
- 1.0.9
- 1.0.9.0
- 1.0.9.0
+ 1.1.0
+ 1.1.0.0
+ 1.1.0.0
app.manifest
latest
diff --git a/MainWindow.xaml b/MainWindow.xaml
index c5c6701..6c8171d 100644
--- a/MainWindow.xaml
+++ b/MainWindow.xaml
@@ -45,7 +45,7 @@
Foreground="{StaticResource TextSecondaryBrush}" Margin="0,-2,0,0"/>
-
@@ -76,6 +76,8 @@
-
+
+
+
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
index 5ab2625..3d74c0b 100644
--- a/MainWindow.xaml.cs
+++ b/MainWindow.xaml.cs
@@ -202,6 +202,11 @@ namespace InstaSoftOfficeTool
return Dialog.ShowAsync(title, message, confirmText, cancelText, type);
}
+ public Task AskProductKeyAsync()
+ {
+ return KeyDialog.ShowAsync();
+ }
+
public void ShowBackToHomeButton()
{
BtnBack.Content = "\u2190 F\u0151oldal";
diff --git a/Pages/ConfigPage.xaml.cs b/Pages/ConfigPage.xaml.cs
index df814c4..24e29eb 100644
--- a/Pages/ConfigPage.xaml.cs
+++ b/Pages/ConfigPage.xaml.cs
@@ -53,10 +53,15 @@ namespace InstaSoftOfficeTool.Pages
? !_config.ExcludedApps.Contains(app.Id)
: app.DefaultChecked;
+ bool isProPlus = _config.Edition != null &&
+ _config.Edition.ProductId.Contains("ProPlus");
+ bool accessOnly = app.Id == "Access";
+
var cb = new CheckBox
{
Content = app.DisplayName,
- IsChecked = isChecked,
+ IsChecked = accessOnly && !isProPlus ? false : isChecked,
+ IsEnabled = !(accessOnly && !isProPlus),
Tag = app.Id,
Style = (Style)FindResource("FluentCheckBox"),
Margin = new Thickness(0, 4, 24, 4),
@@ -79,7 +84,7 @@ namespace InstaSoftOfficeTool.Pages
_config.ExcludedApps.Clear();
foreach (var cb in _appCheckBoxes)
{
- if (cb.IsChecked != true)
+ if (cb.IsChecked != true || !cb.IsEnabled)
{
_config.ExcludedApps.Add((string)cb.Tag);
}
diff --git a/Pages/ProductKeyDialog.xaml b/Pages/ProductKeyDialog.xaml
new file mode 100644
index 0000000..0fa1423
--- /dev/null
+++ b/Pages/ProductKeyDialog.xaml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Pages/ProductKeyDialog.xaml.cs b/Pages/ProductKeyDialog.xaml.cs
new file mode 100644
index 0000000..ab9c747
--- /dev/null
+++ b/Pages/ProductKeyDialog.xaml.cs
@@ -0,0 +1,124 @@
+using System;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+
+namespace InstaSoftOfficeTool.Pages
+{
+ public partial class ProductKeyDialog : UserControl
+ {
+ private TaskCompletionSource _tcs;
+ private readonly TextBox[] _keyBoxes;
+ private bool _suppress;
+
+ public ProductKeyDialog()
+ {
+ InitializeComponent();
+ _keyBoxes = new[] { DKey1, DKey2, DKey3, DKey4, DKey5 };
+
+ foreach (var box in _keyBoxes)
+ {
+ DataObject.AddPastingHandler(box, OnPaste);
+ }
+ }
+
+ public Task ShowAsync()
+ {
+ foreach (var box in _keyBoxes) box.Text = "";
+ BtnOk.IsEnabled = false;
+ Visibility = Visibility.Visible;
+ DKey1.Focus();
+ _tcs = new TaskCompletionSource();
+ return _tcs.Task;
+ }
+
+ private string GetFullKey()
+ {
+ return string.Join("-", DKey1.Text, DKey2.Text, DKey3.Text, DKey4.Text, DKey5.Text).ToUpper();
+ }
+
+ private bool IsKeyComplete()
+ {
+ foreach (var box in _keyBoxes)
+ {
+ if (box.Text.Length != 5 || !Regex.IsMatch(box.Text, "^[A-Za-z0-9]{5}$"))
+ return false;
+ }
+ return true;
+ }
+
+ private void KeyBox_TextChanged(object sender, TextChangedEventArgs e)
+ {
+ if (_suppress) return;
+ var tb = (TextBox)sender;
+
+ var cleaned = Regex.Replace(tb.Text, "[^A-Za-z0-9]", "");
+ if (cleaned != tb.Text)
+ {
+ _suppress = true;
+ tb.Text = cleaned;
+ tb.CaretIndex = cleaned.Length;
+ _suppress = false;
+ }
+
+ if (tb.Text.Length == 5)
+ {
+ for (int i = 0; i < _keyBoxes.Length - 1; i++)
+ {
+ if (_keyBoxes[i] == tb)
+ {
+ _keyBoxes[i + 1].Focus();
+ break;
+ }
+ }
+ }
+
+ BtnOk.IsEnabled = IsKeyComplete();
+ }
+
+ private void OnPaste(object sender, DataObjectPastingEventArgs e)
+ {
+ if (!e.DataObject.GetDataPresent(typeof(string))) return;
+ var pasted = (string)e.DataObject.GetData(typeof(string));
+ var allAlphaNum = Regex.Replace(pasted, "[^A-Za-z0-9]", "");
+
+ if (allAlphaNum.Length <= 5) return;
+
+ e.CancelCommand();
+ _suppress = true;
+ for (int i = 0; i < 5; i++)
+ {
+ int start = i * 5;
+ if (start < allAlphaNum.Length)
+ {
+ int len = Math.Min(5, allAlphaNum.Length - start);
+ _keyBoxes[i].Text = allAlphaNum.Substring(start, len).ToUpper();
+ }
+ }
+ _suppress = false;
+ _keyBoxes[4].Focus();
+ _keyBoxes[4].CaretIndex = _keyBoxes[4].Text.Length;
+ BtnOk.IsEnabled = IsKeyComplete();
+ }
+
+ private void BtnOk_Click(object sender, RoutedEventArgs e)
+ {
+ Visibility = Visibility.Collapsed;
+ _tcs?.TrySetResult(GetFullKey());
+ }
+
+ private void BtnCancel_Click(object sender, RoutedEventArgs e)
+ {
+ Visibility = Visibility.Collapsed;
+ _tcs?.TrySetResult(null);
+ }
+
+ private void Backdrop_MouseDown(object sender, MouseButtonEventArgs e)
+ {
+ Visibility = Visibility.Collapsed;
+ _tcs?.TrySetResult(null);
+ }
+ }
+}
diff --git a/Pages/RemovePage.xaml.cs b/Pages/RemovePage.xaml.cs
index 83e7364..e23045f 100644
--- a/Pages/RemovePage.xaml.cs
+++ b/Pages/RemovePage.xaml.cs
@@ -143,7 +143,13 @@ namespace InstaSoftOfficeTool.Pages
}
AppendLog("");
- AppendLog("K\u00e9sz.");
+ AppendLog("K\u00e9sz. Lista friss\u00edt\u00e9se...");
+ DetectOffice();
+
+ if (_detected.Count == 0)
+ {
+ AppendLog("Nincs t\u00f6bb telep\u00edtett Office.");
+ }
}
catch (Exception ex)
{
@@ -151,6 +157,7 @@ namespace InstaSoftOfficeTool.Pages
AppendLog(ex.StackTrace);
}
+ BtnRemove.IsEnabled = _detected.Count > 0;
_main.ShowCloseButton();
}
diff --git a/Pages/TroubleshootPage.xaml b/Pages/TroubleshootPage.xaml
index d3d30cb..6326894 100644
--- a/Pages/TroubleshootPage.xaml
+++ b/Pages/TroubleshootPage.xaml
@@ -14,7 +14,7 @@
-
diff --git a/Pages/TroubleshootPage.xaml.cs b/Pages/TroubleshootPage.xaml.cs
index 5d5e58a..48fb3a8 100644
--- a/Pages/TroubleshootPage.xaml.cs
+++ b/Pages/TroubleshootPage.xaml.cs
@@ -29,7 +29,6 @@ namespace InstaSoftOfficeTool.Pages
BtnRemoveAll.Visibility = Visibility.Collapsed;
BtnRefresh.IsEnabled = false;
- // Loading indicator
var loadingText = new TextBlock
{
Text = "Keres\u00e9s folyamatban...",
@@ -164,18 +163,38 @@ namespace InstaSoftOfficeTool.Pages
Grid.SetColumn(infoPanel, 0);
grid.Children.Add(infoPanel);
+ // Right side: Activate + Remove buttons
+ var btnPanel = new StackPanel
+ {
+ Orientation = Orientation.Horizontal,
+ VerticalAlignment = VerticalAlignment.Center
+ };
+
+ var activateBtn = new Button
+ {
+ Content = "Aktiv\u00e1l\u00e1s",
+ Style = (Style)FindResource("PrimaryButton"),
+ Padding = new Thickness(14, 6, 14, 6),
+ FontSize = 12,
+ Tag = entry.Last5
+ };
+ activateBtn.Click += BtnActivateSingle_Click;
+ btnPanel.Children.Add(activateBtn);
+
var removeBtn = new Button
{
Content = "Elt\u00e1vol\u00edt\u00e1s",
Style = (Style)FindResource("SecondaryButton"),
Padding = new Thickness(14, 6, 14, 6),
FontSize = 12,
- VerticalAlignment = VerticalAlignment.Center,
- Tag = entry.Last5
+ Tag = entry.Last5,
+ Margin = new Thickness(6, 0, 0, 0)
};
removeBtn.Click += BtnRemoveSingle_Click;
- Grid.SetColumn(removeBtn, 1);
- grid.Children.Add(removeBtn);
+ btnPanel.Children.Add(removeBtn);
+
+ Grid.SetColumn(btnPanel, 1);
+ grid.Children.Add(btnPanel);
return new Border
{
@@ -189,6 +208,37 @@ namespace InstaSoftOfficeTool.Pages
};
}
+ private async void BtnActivateSingle_Click(object sender, RoutedEventArgs e)
+ {
+ string key = await _main.AskProductKeyAsync();
+ if (string.IsNullOrEmpty(key)) return;
+
+ var btn = (Button)sender;
+ btn.IsEnabled = false;
+ btn.Content = "...";
+
+ DetailsExpander.IsExpanded = true;
+ OutputText.Text = "Term\u00e9kkulcs telep\u00edt\u00e9se: " + key + "\n";
+
+ try
+ {
+ string inpResult = await _licenseManager.InstallKeyAsync(key);
+ OutputText.Text += inpResult + "\n";
+
+ OutputText.Text += "Aktiv\u00e1l\u00e1s...\n";
+ string actResult = await _licenseManager.ActivateAsync();
+ OutputText.Text += actResult;
+
+ await RefreshStatus();
+ }
+ catch (Exception ex)
+ {
+ OutputText.Text += "\nHiba: " + ex.Message;
+ btn.IsEnabled = true;
+ btn.Content = "Aktiv\u00e1l\u00e1s";
+ }
+ }
+
private async void BtnRemoveSingle_Click(object sender, RoutedEventArgs e)
{
var btn = (Button)sender;
@@ -250,17 +300,12 @@ namespace InstaSoftOfficeTool.Pages
private void DetailsExpander_Expanded(object sender, RoutedEventArgs e)
{
- // Grow window to fit details
- var window = Window.GetWindow(this);
- if (window != null && window.Height < 680)
- window.Height = 680;
+ _main.Height = 680;
}
private void DetailsExpander_Collapsed(object sender, RoutedEventArgs e)
{
- var window = Window.GetWindow(this);
- if (window != null)
- window.Height = 550;
+ _main.Height = 550;
}
}
}
diff --git a/Services/LicenseManager.cs b/Services/LicenseManager.cs
index adfb797..b81a359 100644
--- a/Services/LicenseManager.cs
+++ b/Services/LicenseManager.cs
@@ -161,5 +161,25 @@ namespace InstaSoftOfficeTool.Services
return string.Join("\n", results);
}
+
+ public async Task 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 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");
+ }
}
}
diff --git a/Services/OfficeDetector.cs b/Services/OfficeDetector.cs
index 115227e..9464ad0 100644
--- a/Services/OfficeDetector.cs
+++ b/Services/OfficeDetector.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Text.RegularExpressions;
using InstaSoftOfficeTool.Models;
using Microsoft.Win32;
@@ -92,11 +93,14 @@ namespace InstaSoftOfficeTool.Services
!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 = subKeyName,
+ ProductCode = isGuid ? subKeyName : null,
IsClickToRun = false,
IsSelected = true
});