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:
hariel1985
2026-04-02 07:07:27 +02:00
szülő ae4d7f82bc
commit 486589f9bc
44 fájl változott, egészen pontosan 0 új sor hozzáadva és 1155 régi sor törölve

43
Pages/ConfigPage.xaml Normal file
Fájl megtekintése

@@ -0,0 +1,43 @@
<Page x:Class="InstaSoftOfficeTool.Pages.ConfigPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent">
<ScrollViewer VerticalScrollBarVisibility="Auto" Margin="40,30">
<StackPanel>
<TextBlock Text="Beállítások" FontSize="24" FontWeight="Light" Margin="0,0,0,20"/>
<!-- Arch + Language side by side -->
<Grid Margin="0,0,0,20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Margin="0,0,16,0">
<TextBlock Text="Architektúra" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,8"/>
<StackPanel Orientation="Horizontal">
<RadioButton x:Name="Rb64" GroupName="Arch" IsChecked="True"
Style="{StaticResource CardRadioButton}" Margin="0,0,10,0" MinWidth="140">
<TextBlock Text="64-bit (ajánlott)" FontSize="14" Margin="6,0"/>
</RadioButton>
<RadioButton x:Name="Rb32" GroupName="Arch"
Style="{StaticResource CardRadioButton}" MinWidth="100">
<TextBlock Text="32-bit" FontSize="14" Margin="6,0"/>
</RadioButton>
</StackPanel>
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock Text="Telepítési nyelv" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,8"/>
<ComboBox x:Name="CbLanguage" Style="{StaticResource FluentComboBox}"
HorizontalAlignment="Stretch"/>
</StackPanel>
</Grid>
<TextBlock Text="Telepítendő alkalmazások" FontSize="15" FontWeight="SemiBold" Margin="0,0,0,10"/>
<WrapPanel x:Name="AppCheckBoxes" Orientation="Horizontal"/>
</StackPanel>
</ScrollViewer>
</Page>

103
Pages/ConfigPage.xaml.cs Normal file
Fájl megtekintése

@@ -0,0 +1,103 @@
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using InstaSoftOfficeTool.Models;
namespace InstaSoftOfficeTool.Pages
{
public partial class ConfigPage : Page, IWizardPage
{
private readonly MainWindow _main;
private readonly InstallConfig _config;
private readonly List<CheckBox> _appCheckBoxes = new List<CheckBox>();
public ConfigPage(MainWindow main, InstallConfig config)
{
InitializeComponent();
_main = main;
_config = config;
// Restore arch
if (_config.Architecture == "32")
{
Rb32.IsChecked = true;
}
// Populate language combo
foreach (var lang in LanguageList.Languages)
{
CbLanguage.Items.Add(new ComboBoxItem
{
Content = lang.Name + " (" + lang.Code + ")",
Tag = lang.Code
});
}
// Select current language
for (int i = 0; i < CbLanguage.Items.Count; i++)
{
var item = (ComboBoxItem)CbLanguage.Items[i];
if ((string)item.Tag == _config.Language)
{
CbLanguage.SelectedIndex = i;
break;
}
}
if (CbLanguage.SelectedIndex < 0) CbLanguage.SelectedIndex = 0;
// Populate app checkboxes
foreach (var app in ExcludableApps.Apps)
{
// Ha m\u00e1r van ment\u00e9s a configban, azt haszn\u00e1ljuk; k\u00fcl\u00f6nben a default\u00f6t
bool isChecked = _config.ExcludedApps.Count > 0
? !_config.ExcludedApps.Contains(app.Id)
: app.DefaultChecked;
bool isProPlus = _config.Edition != null &&
_config.Edition.ProductId.Contains("ProPlus");
bool isStandard = _config.Edition != null &&
_config.Edition.ProductId.Contains("Standard");
bool unavailable = false;
if (app.MinEdition == "proplus" && !isProPlus)
unavailable = true;
else if (app.MinEdition == "standard+" && !isProPlus && !isStandard)
unavailable = true;
var cb = new CheckBox
{
Content = app.DisplayName,
IsChecked = unavailable ? false : isChecked,
IsEnabled = !unavailable,
Tag = app.Id,
Style = (Style)FindResource("FluentCheckBox"),
Margin = new Thickness(0, 4, 24, 4),
MinWidth = 160
};
_appCheckBoxes.Add(cb);
AppCheckBoxes.Children.Add(cb);
}
}
public bool Validate()
{
_config.Architecture = Rb64.IsChecked == true ? "64" : "32";
if (CbLanguage.SelectedItem is ComboBoxItem selected)
{
_config.Language = (string)selected.Tag;
}
_config.ExcludedApps.Clear();
foreach (var cb in _appCheckBoxes)
{
if (cb.IsChecked != true || !cb.IsEnabled)
{
_config.ExcludedApps.Add((string)cb.Tag);
}
}
return true;
}
}
}

41
Pages/ConfirmDialog.xaml Normal file
Fájl megtekintése

@@ -0,0 +1,41 @@
<UserControl x:Class="InstaSoftOfficeTool.Pages.ConfirmDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Visibility="Collapsed">
<!-- Backdrop overlay -->
<Grid>
<Border Background="#66000000" MouseDown="Backdrop_MouseDown"/>
<!-- Dialog card -->
<Border Background="{StaticResource CardBrush}" CornerRadius="12"
HorizontalAlignment="Center" VerticalAlignment="Center"
MinWidth="400" MaxWidth="500" Padding="28,24">
<Border.Effect>
<DropShadowEffect ShadowDepth="8" BlurRadius="32" Opacity="0.2" Color="Black"/>
</Border.Effect>
<StackPanel>
<!-- Icon + Title -->
<StackPanel Orientation="Horizontal" Margin="0,0,0,12">
<TextBlock x:Name="DialogIcon" FontFamily="Segoe MDL2 Assets" FontSize="22"
VerticalAlignment="Center" Margin="0,0,12,0"/>
<TextBlock x:Name="DialogTitle" FontSize="18" FontWeight="SemiBold"
VerticalAlignment="Center"/>
</StackPanel>
<!-- Message -->
<TextBlock x:Name="DialogMessage" FontSize="14" TextWrapping="Wrap"
Foreground="{StaticResource TextSecondaryBrush}" Margin="0,0,0,24"/>
<!-- Buttons -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="BtnCancel" Style="{StaticResource SecondaryButton}"
Click="BtnCancel_Click" Margin="0,0,8,0"/>
<Button x:Name="BtnConfirm" Style="{StaticResource PrimaryButton}"
Click="BtnConfirm_Click"/>
</StackPanel>
</StackPanel>
</Border>
</Grid>
</UserControl>

Fájl megtekintése

@@ -0,0 +1,75 @@
using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace InstaSoftOfficeTool.Pages
{
public partial class ConfirmDialog : UserControl
{
private TaskCompletionSource<bool> _tcs;
public ConfirmDialog()
{
InitializeComponent();
}
public Task<bool> ShowAsync(string title, string message,
string confirmText = "Igen", string cancelText = "M\u00e9gse",
DialogType type = DialogType.Warning)
{
DialogTitle.Text = title;
DialogMessage.Text = message;
BtnConfirm.Content = confirmText;
BtnCancel.Content = cancelText;
switch (type)
{
case DialogType.Warning:
DialogIcon.Text = "\uE7BA";
DialogIcon.Foreground = (Brush)FindResource("WarningBrush");
break;
case DialogType.Question:
DialogIcon.Text = "\uE9CE";
DialogIcon.Foreground = (Brush)FindResource("AccentBrush");
break;
case DialogType.Error:
DialogIcon.Text = "\uE711";
DialogIcon.Foreground = (Brush)FindResource("ErrorBrush");
break;
}
Visibility = Visibility.Visible;
_tcs = new TaskCompletionSource<bool>();
return _tcs.Task;
}
private void BtnConfirm_Click(object sender, RoutedEventArgs e)
{
Visibility = Visibility.Collapsed;
_tcs?.TrySetResult(true);
}
private void BtnCancel_Click(object sender, RoutedEventArgs e)
{
Visibility = Visibility.Collapsed;
_tcs?.TrySetResult(false);
}
private void Backdrop_MouseDown(object sender, MouseButtonEventArgs e)
{
// click outside = cancel
Visibility = Visibility.Collapsed;
_tcs?.TrySetResult(false);
}
}
public enum DialogType
{
Warning,
Question,
Error
}
}

20
Pages/EditionPage.xaml Normal file
Fájl megtekintése

@@ -0,0 +1,20 @@
<Page x:Class="InstaSoftOfficeTool.Pages.EditionPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent">
<Grid Margin="40,30">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="0,0,0,24">
<TextBlock x:Name="TitleText" Text="Valasszon kiadast" FontSize="24" FontWeight="Light"/>
<TextBlock x:Name="SubtitleText" FontSize="14"
Foreground="{StaticResource TextSecondaryBrush}" Margin="0,4,0,0"/>
</StackPanel>
<StackPanel x:Name="EditionPanel" Grid.Row="1" VerticalAlignment="Top"/>
</Grid>
</Page>

80
Pages/EditionPage.xaml.cs Normal file
Fájl megtekintése

@@ -0,0 +1,80 @@
using System.Windows;
using System.Windows.Controls;
using InstaSoftOfficeTool.Models;
namespace InstaSoftOfficeTool.Pages
{
public partial class EditionPage : Page, IWizardPage
{
private readonly MainWindow _main;
private readonly InstallConfig _config;
private readonly OfficeEdition[] _editions;
public EditionPage(MainWindow main, InstallConfig config)
{
InitializeComponent();
_main = main;
_config = config;
_editions = OfficeEdition.GetEditions(_config.Version);
SubtitleText.Text = _config.GetVersionDisplayName() + " — melyik kiadast szeretne?";
BuildEditionCards();
}
private void BuildEditionCards()
{
EditionPanel.Children.Clear();
for (int i = 0; i < _editions.Length; i++)
{
var edition = _editions[i];
var rb = new RadioButton
{
GroupName = "Edition",
IsChecked = i == 0 || (_config.Edition != null && _config.Edition.ProductId == edition.ProductId),
Style = (Style)FindResource("CardRadioButton"),
Margin = new Thickness(0, 0, 0, 10),
Tag = i
};
var sp = new StackPanel { Margin = new Thickness(8, 2, 8, 2) };
var titleBlock = new TextBlock
{
Text = edition.DisplayName,
FontSize = 18,
FontWeight = FontWeights.SemiBold
};
sp.Children.Add(titleBlock);
var descBlock = new TextBlock
{
Text = edition.Description,
FontSize = 12,
Foreground = (System.Windows.Media.Brush)FindResource("TextSecondaryBrush"),
TextWrapping = TextWrapping.Wrap,
Margin = new Thickness(0, 2, 0, 0)
};
sp.Children.Add(descBlock);
rb.Content = sp;
EditionPanel.Children.Add(rb);
}
}
public bool Validate()
{
foreach (var child in EditionPanel.Children)
{
if (child is RadioButton rb && rb.IsChecked == true)
{
int idx = (int)rb.Tag;
_config.Edition = _editions[idx];
return true;
}
}
return false;
}
}
}

Fájl megtekintése

@@ -0,0 +1,67 @@
<Page x:Class="InstaSoftOfficeTool.Pages.PreInstallCheckPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent">
<Grid Margin="40,30">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="0,0,0,16">
<TextBlock Text="Meglévő Office ellenőrzése" FontSize="24" FontWeight="Light"/>
<TextBlock x:Name="SubtitleText" FontSize="14"
Foreground="{StaticResource TextSecondaryBrush}" Margin="0,4,0,0"/>
</StackPanel>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<StackPanel>
<StackPanel x:Name="OfficeListPanel"/>
<!-- No office found card -->
<Border x:Name="NoOfficeCard" Visibility="Collapsed"
Background="{StaticResource CardBrush}" CornerRadius="8"
BorderBrush="{StaticResource BorderBrush}" BorderThickness="1"
Padding="16,14">
<StackPanel Orientation="Horizontal">
<TextBlock Text="&#xE73E;" FontFamily="Segoe MDL2 Assets" FontSize="18"
Foreground="{StaticResource SuccessBrush}" VerticalAlignment="Center"
Margin="0,0,12,0"/>
<TextBlock Text="Nem található telepített Office. A telepítés indítható."
FontSize="14" VerticalAlignment="Center"/>
</StackPanel>
</Border>
<!-- License cleanup -->
<Border x:Name="LicenseCleanupPanel" Margin="0,12,0,0" Visibility="Collapsed"
Background="{StaticResource CardBrush}" CornerRadius="8"
BorderBrush="{StaticResource BorderBrush}" BorderThickness="1"
Padding="16,12">
<CheckBox x:Name="CbCleanLicense" Style="{StaticResource FluentCheckBox}"
Content="Licenc-adatbázis tisztítása is (ajánlott)"
IsChecked="True"/>
</Border>
<!-- Log -->
<Border x:Name="LogPanel" Margin="0,12,0,0" Background="#F8F8F8"
CornerRadius="6" Padding="12" Visibility="Collapsed"
BorderBrush="{StaticResource BorderBrush}" BorderThickness="1">
<TextBox x:Name="LogText" FontFamily="Consolas" FontSize="11"
TextWrapping="Wrap" Foreground="{StaticResource TextSecondaryBrush}"
IsReadOnly="True" Background="Transparent" BorderThickness="0"
VerticalScrollBarVisibility="Auto" AcceptsReturn="True" MaxHeight="150"/>
</Border>
</StackPanel>
</ScrollViewer>
<!-- Buttons -->
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,12,0,0">
<Button x:Name="BtnSkip" Content="Kihagyás, telepítés folytatása"
Style="{StaticResource SecondaryButton}" Click="BtnSkip_Click" Margin="0,0,8,0"/>
<Button x:Name="BtnRemove" Content="Eltávolítás, majd telepítés"
Style="{StaticResource PrimaryButton}" Click="BtnRemove_Click" Visibility="Collapsed"/>
</StackPanel>
</Grid>
</Page>

Fájl megtekintése

@@ -0,0 +1,164 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using InstaSoftOfficeTool.Models;
using InstaSoftOfficeTool.Services;
namespace InstaSoftOfficeTool.Pages
{
public partial class PreInstallCheckPage : Page
{
private readonly MainWindow _main;
private List<InstalledOffice> _detected;
public PreInstallCheckPage(MainWindow main)
{
InitializeComponent();
_main = main;
Loaded += (s, e) => DetectOffice();
}
private void DetectOffice()
{
_detected = OfficeDetector.Detect();
OfficeListPanel.Children.Clear();
if (_detected.Count == 0)
{
SubtitleText.Text = "Nincs kor\u00e1bbi Office telep\u00edt\u00e9s a g\u00e9pen.";
NoOfficeCard.Visibility = Visibility.Visible;
BtnRemove.Visibility = Visibility.Collapsed;
LicenseCleanupPanel.Visibility = Visibility.Collapsed;
BtnSkip.Content = "Tov\u00e1bb a telep\u00edt\u00e9shez \u2192";
return;
}
SubtitleText.Text = "A sz\u00e1m\u00edt\u00f3g\u00e9pen tal\u00e1lt Office telep\u00edt\u00e9sek. Az \u00faj Office telep\u00edt\u00e9se el\u0151tt aj\u00e1nlott elt\u00e1vol\u00edtani.";
BtnRemove.Visibility = Visibility.Visible;
LicenseCleanupPanel.Visibility = Visibility.Visible;
foreach (var office in _detected)
{
var cb = new CheckBox
{
Content = office.DisplayName +
(string.IsNullOrEmpty(office.Version) ? "" : " (" + office.Version + ")"),
IsChecked = true,
Style = (Style)FindResource("FluentCheckBox"),
Tag = office,
Margin = new Thickness(0, 4, 0, 4),
FontSize = 14
};
OfficeListPanel.Children.Add(cb);
}
}
private void BtnSkip_Click(object sender, RoutedEventArgs e)
{
_main.ProceedToInstall();
}
private async void BtnRemove_Click(object sender, RoutedEventArgs e)
{
bool confirmed = await _main.ConfirmAsync(
"Office elt\u00e1vol\u00edt\u00e1s",
"Biztosan el szeretn\u00e9 t\u00e1vol\u00edtani a kiv\u00e1lasztott Office telep\u00edt\u00e9seket az \u00faj verzi\u00f3 telep\u00edt\u00e9se el\u0151tt?",
"Elt\u00e1vol\u00edt\u00e1s", "M\u00e9gse");
if (!confirmed) return;
BtnRemove.IsEnabled = false;
BtnSkip.IsEnabled = false;
LogPanel.Visibility = Visibility.Visible;
try
{
var c2rProducts = new System.Collections.Generic.List<string>();
foreach (UIElement child in OfficeListPanel.Children)
{
if (child is CheckBox cb && cb.IsChecked == true)
{
var office = (InstalledOffice)cb.Tag;
if (office.IsClickToRun)
{
c2rProducts.Add(office.ProductCode);
}
else if (!string.IsNullOrEmpty(office.ProductCode))
{
AppendLog("MSI elt\u00e1vol\u00edt\u00e1s: " + office.DisplayName);
var runner = new ProcessRunner();
runner.OutputReceived += msg => Dispatcher.Invoke(() => AppendLog(msg));
int code = await runner.RunAsync("msiexec", "/x " + office.ProductCode + " /qb");
AppendLog("MSI exit code: " + code);
}
}
}
if (c2rProducts.Count > 0)
{
AppendLog("Click-to-Run term\u00e9kek elt\u00e1vol\u00edt\u00e1sa: " + string.Join(", ", c2rProducts));
var downloader = new OdtDownloader();
downloader.StatusChanged += msg => Dispatcher.Invoke(() => AppendLog(msg));
bool ok = await downloader.DownloadAndExtractAsync();
if (!ok)
{
AppendLog("HIBA: Az ODT let\u00f6lt\u00e9se sikertelen.");
BtnRemove.IsEnabled = true;
BtnSkip.IsEnabled = true;
return;
}
string removeXml = OdtXmlGenerator.GenerateRemoveProducts(c2rProducts.ToArray());
string xmlPath = Path.Combine(downloader.OdtFolder, "remove.xml");
File.WriteAllText(xmlPath, removeXml);
AppendLog("Futtat\u00e1s: setup.exe /configure remove.xml");
AppendLog("Ez eltarthat n\u00e9h\u00e1ny percig...");
int exitCode = await downloader.RunRemoveAsync(xmlPath,
msg => Dispatcher.Invoke(() => AppendLog(msg)));
AppendLog("setup.exe exit code: " + exitCode);
AppendLog(exitCode == 0
? "Office sikeresen elt\u00e1vol\u00edtva."
: "FIGYELEM: Az elt\u00e1vol\u00edt\u00e1s nem siker\u00fclt (k\u00f3d: " + exitCode + ")");
}
if (CbCleanLicense.IsChecked == true)
{
AppendLog("Licenc-adatb\u00e1zis tiszt\u00edt\u00e1sa...");
var lm = new LicenseManager();
if (lm.FindOspp())
{
var cleanResult = await lm.RemoveAllKeysAsync();
AppendLog(cleanResult);
}
else
{
AppendLog("Az ospp.vbs nem tal\u00e1lhat\u00f3 \u2014 licenc-tiszt\u00edt\u00e1s kihagyva.");
}
}
AppendLog("K\u00e9sz. Tov\u00e1bbl\u00e9p\u00e9s az \u00faj Office telep\u00edt\u00e9s\u00e9hez...");
}
catch (Exception ex)
{
AppendLog("V\u00e1ratlan hiba: " + ex.Message);
}
await System.Threading.Tasks.Task.Delay(2000);
_main.ProceedToInstall();
}
private void AppendLog(string text)
{
LogText.Text += DateTime.Now.ToString("HH:mm:ss") + " " + text + "\n";
LogText.ScrollToEnd();
}
}
}

Fájl megtekintése

@@ -0,0 +1,69 @@
<UserControl x:Class="InstaSoftOfficeTool.Pages.ProductKeyDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Visibility="Collapsed">
<Grid>
<Border Background="#66000000" MouseDown="Backdrop_MouseDown"/>
<Border Background="{StaticResource CardBrush}" CornerRadius="12"
HorizontalAlignment="Center" VerticalAlignment="Center"
MinWidth="480" Padding="28,24">
<Border.Effect>
<DropShadowEffect ShadowDepth="8" BlurRadius="32" Opacity="0.2" Color="Black"/>
</Border.Effect>
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,8">
<TextBlock Text="&#xE8D7;" FontFamily="Segoe MDL2 Assets" FontSize="22"
Foreground="{StaticResource AccentBrush}"
VerticalAlignment="Center" Margin="0,0,12,0"/>
<TextBlock Text="Termékkulcs megadása" FontSize="18" FontWeight="SemiBold"
VerticalAlignment="Center"/>
</StackPanel>
<TextBlock Text="Adja meg a 25 karakteres termékkulcsot az aktiváláshoz."
FontSize="13" Foreground="{StaticResource TextSecondaryBrush}"
Margin="0,0,0,16"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,20">
<TextBox x:Name="DKey1" Style="{StaticResource FluentTextBox}"
Width="76" MaxLength="5" CharacterCasing="Upper"
FontFamily="Consolas" FontSize="15" TextAlignment="Center"
TextChanged="KeyBox_TextChanged"/>
<TextBlock Text="-" FontSize="18" VerticalAlignment="Center" Margin="4,0"
Foreground="{StaticResource TextSecondaryBrush}"/>
<TextBox x:Name="DKey2" Style="{StaticResource FluentTextBox}"
Width="76" MaxLength="5" CharacterCasing="Upper"
FontFamily="Consolas" FontSize="15" TextAlignment="Center"
TextChanged="KeyBox_TextChanged"/>
<TextBlock Text="-" FontSize="18" VerticalAlignment="Center" Margin="4,0"
Foreground="{StaticResource TextSecondaryBrush}"/>
<TextBox x:Name="DKey3" Style="{StaticResource FluentTextBox}"
Width="76" MaxLength="5" CharacterCasing="Upper"
FontFamily="Consolas" FontSize="15" TextAlignment="Center"
TextChanged="KeyBox_TextChanged"/>
<TextBlock Text="-" FontSize="18" VerticalAlignment="Center" Margin="4,0"
Foreground="{StaticResource TextSecondaryBrush}"/>
<TextBox x:Name="DKey4" Style="{StaticResource FluentTextBox}"
Width="76" MaxLength="5" CharacterCasing="Upper"
FontFamily="Consolas" FontSize="15" TextAlignment="Center"
TextChanged="KeyBox_TextChanged"/>
<TextBlock Text="-" FontSize="18" VerticalAlignment="Center" Margin="4,0"
Foreground="{StaticResource TextSecondaryBrush}"/>
<TextBox x:Name="DKey5" Style="{StaticResource FluentTextBox}"
Width="76" MaxLength="5" CharacterCasing="Upper"
FontFamily="Consolas" FontSize="15" TextAlignment="Center"
TextChanged="KeyBox_TextChanged"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="Mégse" Style="{StaticResource SecondaryButton}"
Click="BtnCancel_Click" Margin="0,0,8,0"/>
<Button x:Name="BtnOk" Content="Aktiválás" Style="{StaticResource PrimaryButton}"
Click="BtnOk_Click" IsEnabled="False"/>
</StackPanel>
</StackPanel>
</Border>
</Grid>
</UserControl>

Fájl megtekintése

@@ -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<string> _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<string> ShowAsync()
{
foreach (var box in _keyBoxes) box.Text = "";
BtnOk.IsEnabled = false;
Visibility = Visibility.Visible;
DKey1.Focus();
_tcs = new TaskCompletionSource<string>();
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);
}
}
}

62
Pages/ProductKeyPage.xaml Normal file
Fájl megtekintése

@@ -0,0 +1,62 @@
<Page x:Class="InstaSoftOfficeTool.Pages.ProductKeyPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent">
<Grid Margin="40,30">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="0,0,0,24">
<TextBlock Text="Termékkulcs" FontSize="24" FontWeight="Light"/>
<TextBlock Text="Adja meg a 25 karakteres termékkulcsot, vagy hagyja üresen."
FontSize="14" Foreground="{StaticResource TextSecondaryBrush}" Margin="0,4,0,0"/>
</StackPanel>
<StackPanel Grid.Row="1" VerticalAlignment="Top">
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
<TextBox x:Name="Key1" Style="{StaticResource FluentTextBox}"
Width="110" MaxLength="5" CharacterCasing="Upper"
TextChanged="KeyBox_TextChanged" FontFamily="Consolas" TextAlignment="Center"/>
<TextBlock Text="-" FontSize="20" VerticalAlignment="Center" Margin="6,0"
Foreground="{StaticResource TextSecondaryBrush}"/>
<TextBox x:Name="Key2" Style="{StaticResource FluentTextBox}"
Width="110" MaxLength="5" CharacterCasing="Upper"
TextChanged="KeyBox_TextChanged" FontFamily="Consolas" TextAlignment="Center"/>
<TextBlock Text="-" FontSize="20" VerticalAlignment="Center" Margin="6,0"
Foreground="{StaticResource TextSecondaryBrush}"/>
<TextBox x:Name="Key3" Style="{StaticResource FluentTextBox}"
Width="110" MaxLength="5" CharacterCasing="Upper"
TextChanged="KeyBox_TextChanged" FontFamily="Consolas" TextAlignment="Center"/>
<TextBlock Text="-" FontSize="20" VerticalAlignment="Center" Margin="6,0"
Foreground="{StaticResource TextSecondaryBrush}"/>
<TextBox x:Name="Key4" Style="{StaticResource FluentTextBox}"
Width="110" MaxLength="5" CharacterCasing="Upper"
TextChanged="KeyBox_TextChanged" FontFamily="Consolas" TextAlignment="Center"/>
<TextBlock Text="-" FontSize="20" VerticalAlignment="Center" Margin="6,0"
Foreground="{StaticResource TextSecondaryBrush}"/>
<TextBox x:Name="Key5" Style="{StaticResource FluentTextBox}"
Width="110" MaxLength="5" CharacterCasing="Upper"
TextChanged="KeyBox_TextChanged" FontFamily="Consolas" TextAlignment="Center"/>
</StackPanel>
<CheckBox x:Name="CbSkipKey" Style="{StaticResource FluentCheckBox}"
Content="Később szeretném megadni"
Margin="0,20,0,0" Checked="CbSkipKey_Changed" Unchecked="CbSkipKey_Changed"/>
<Border Background="#FFF8E1" CornerRadius="6" Padding="16,12" Margin="0,24,0,0"
BorderBrush="#FFE082" BorderThickness="1" MaxWidth="600" HorizontalAlignment="Left">
<StackPanel>
<TextBlock Text="Tudnivaló" FontWeight="SemiBold" FontSize="13" Margin="0,0,0,4"/>
<TextBlock TextWrapping="Wrap" FontSize="12" Foreground="{StaticResource TextSecondaryBrush}"
Text="Ha megadja a termékkulcsot, az Office automatikusan aktiválódik a telepítés után. Ha nem adja meg, későbbi időpontban is megadható az Office alkalmazáson belül (Fájl > Fiók > Termékkulcs módosítása)."/>
</StackPanel>
</Border>
<TextBlock x:Name="ValidationMessage" FontSize="12" Margin="0,12,0,0"
Foreground="{StaticResource ErrorBrush}" Visibility="Collapsed"/>
</StackPanel>
</Grid>
</Page>

Fájl megtekintése

@@ -0,0 +1,149 @@
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using InstaSoftOfficeTool.Models;
namespace InstaSoftOfficeTool.Pages
{
public partial class ProductKeyPage : Page, IWizardPage
{
private readonly MainWindow _main;
private readonly InstallConfig _config;
private readonly TextBox[] _keyBoxes;
private bool _suppressAutoTab;
public ProductKeyPage(MainWindow main, InstallConfig config)
{
InitializeComponent();
_main = main;
_config = config;
_keyBoxes = new[] { Key1, Key2, Key3, Key4, Key5 };
if (!string.IsNullOrEmpty(_config.ProductKey))
{
var parts = _config.ProductKey.Split('-');
for (int i = 0; i < parts.Length && i < 5; i++)
{
_keyBoxes[i].Text = parts[i];
}
}
// Intercept paste on all boxes
foreach (var box in _keyBoxes)
{
DataObject.AddPastingHandler(box, OnPaste);
}
}
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]", "");
// Only intercept if it looks like a full key (more than 5 chars)
if (allAlphaNum.Length <= 5) return;
e.CancelCommand(); // prevent default paste
_suppressAutoTab = true;
for (int i = 0; i < 5; i++)
{
int start = i * 5;
if (start < allAlphaNum.Length)
{
int len = System.Math.Min(5, allAlphaNum.Length - start);
_keyBoxes[i].Text = allAlphaNum.Substring(start, len).ToUpper();
}
}
_suppressAutoTab = false;
_keyBoxes[4].Focus();
_keyBoxes[4].CaretIndex = _keyBoxes[4].Text.Length;
ValidationMessage.Visibility = Visibility.Collapsed;
}
private void KeyBox_TextChanged(object sender, TextChangedEventArgs e)
{
if (_suppressAutoTab) return;
var tb = (TextBox)sender;
var raw = tb.Text;
// Clean non-alphanumeric chars
var cleaned = Regex.Replace(raw, "[^A-Za-z0-9]", "");
if (cleaned != raw)
{
_suppressAutoTab = true;
tb.Text = cleaned;
tb.CaretIndex = cleaned.Length;
_suppressAutoTab = false;
}
// Auto-tab to next box when 5 chars entered
if (tb.Text.Length == 5)
{
for (int i = 0; i < _keyBoxes.Length - 1; i++)
{
if (_keyBoxes[i] == tb)
{
_keyBoxes[i + 1].Focus();
break;
}
}
}
ValidationMessage.Visibility = Visibility.Collapsed;
}
private void CbSkipKey_Changed(object sender, RoutedEventArgs e)
{
bool skip = CbSkipKey.IsChecked == true;
foreach (var box in _keyBoxes)
{
box.IsEnabled = !skip;
if (skip) box.Text = "";
}
ValidationMessage.Visibility = Visibility.Collapsed;
}
public bool Validate()
{
if (CbSkipKey.IsChecked == true)
{
_config.ProductKey = null;
return true;
}
bool allEmpty = true;
foreach (var box in _keyBoxes)
{
if (!string.IsNullOrEmpty(box.Text))
{
allEmpty = false;
break;
}
}
if (allEmpty)
{
_config.ProductKey = null;
return true;
}
foreach (var box in _keyBoxes)
{
if (box.Text.Length != 5 || !Regex.IsMatch(box.Text, "^[A-Za-z0-9]{5}$"))
{
ValidationMessage.Text = "A term\u00e9kkulcsnak 5 x 5 alfanumerikus karakterb\u0151l kell \u00e1llnia.";
ValidationMessage.Visibility = Visibility.Visible;
return false;
}
}
_config.ProductKey = string.Join("-",
Key1.Text, Key2.Text, Key3.Text, Key4.Text, Key5.Text).ToUpper();
return true;
}
}
}

87
Pages/ProgressPage.xaml Normal file
Fájl megtekintése

@@ -0,0 +1,87 @@
<Page x:Class="InstaSoftOfficeTool.Pages.ProgressPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent">
<ScrollViewer VerticalScrollBarVisibility="Auto" Margin="40,30">
<StackPanel>
<TextBlock x:Name="TitleText" Text="Telepítés folyamatban..."
FontSize="24" FontWeight="Light" Margin="0,0,0,20"/>
<StackPanel Margin="0,0,0,16">
<StackPanel Orientation="Horizontal" Margin="0,4">
<TextBlock x:Name="Step1Icon" Text="&#xE73E;" FontFamily="Segoe MDL2 Assets"
FontSize="14" Foreground="{StaticResource TextSecondaryBrush}" Width="24"/>
<TextBlock x:Name="Step1Text" Text="Office Deployment Tool letöltése..."
Foreground="{StaticResource TextSecondaryBrush}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,4">
<TextBlock x:Name="Step2Icon" Text="&#xE73E;" FontFamily="Segoe MDL2 Assets"
FontSize="14" Foreground="{StaticResource TextSecondaryBrush}" Width="24"/>
<TextBlock x:Name="Step2Text" Text="Konfiguráció generálása..."
Foreground="{StaticResource TextSecondaryBrush}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,4">
<TextBlock x:Name="Step3Icon" Text="&#xE73E;" FontFamily="Segoe MDL2 Assets"
FontSize="14" Foreground="{StaticResource TextSecondaryBrush}" Width="24"/>
<TextBlock x:Name="Step3Text" Text="Office telepítése... (akár 30-40 percet is igénybe vehet)"
Foreground="{StaticResource TextSecondaryBrush}"/>
</StackPanel>
</StackPanel>
<ProgressBar x:Name="MainProgress" Style="{StaticResource FluentProgressBar}"
IsIndeterminate="True" Margin="0,0,0,0"/>
<Border Background="#F8F8F8" CornerRadius="6" Padding="12" Margin="0,12,0,0"
BorderBrush="{StaticResource BorderBrush}" BorderThickness="1">
<TextBox x:Name="LogText" FontFamily="Consolas" FontSize="11"
TextWrapping="Wrap" Foreground="{StaticResource TextSecondaryBrush}"
IsReadOnly="True" Background="Transparent" BorderThickness="0"
VerticalScrollBarVisibility="Auto" AcceptsReturn="True"/>
</Border>
<!-- Done panel -->
<StackPanel x:Name="DonePanel" Margin="0,12,0,0" Visibility="Collapsed">
<!-- Status message -->
<StackPanel Orientation="Horizontal" Margin="0,0,0,12">
<TextBlock x:Name="DoneIcon" FontFamily="Segoe MDL2 Assets" FontSize="20"
VerticalAlignment="Center" Margin="0,0,8,0"/>
<TextBlock x:Name="DoneText" FontSize="15" FontWeight="SemiBold" VerticalAlignment="Center"/>
</StackPanel>
<!-- Activate card (only if no key was provided) -->
<Border x:Name="ActivateCard" Visibility="Collapsed"
Background="{StaticResource CardBrush}" CornerRadius="8"
BorderBrush="{StaticResource BorderBrush}" BorderThickness="1"
Padding="16,12" Margin="0,0,0,12">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="Termékkulcs megadása" FontSize="14" FontWeight="SemiBold"/>
<TextBlock Text="Az Office aktiválásához adja meg a termékkulcsot."
FontSize="12" Foreground="{StaticResource TextSecondaryBrush}"/>
</StackPanel>
<Button x:Name="BtnActivateNow" Grid.Column="1" Content="Aktiválás"
Style="{StaticResource PrimaryButton}" Click="BtnActivateNow_Click"
VerticalAlignment="Center" Padding="18,8"/>
</Grid>
</Border>
<!-- Launch apps -->
<Border x:Name="LaunchCard" Visibility="Collapsed"
Background="{StaticResource CardBrush}" CornerRadius="8"
BorderBrush="{StaticResource BorderBrush}" BorderThickness="1"
Padding="16,12" Margin="0,0,0,8">
<StackPanel>
<TextBlock Text="Alkalmazás indítása" FontSize="14" FontWeight="SemiBold" Margin="0,0,0,10"/>
<WrapPanel x:Name="LaunchButtons" Orientation="Horizontal"/>
</StackPanel>
</Border>
</StackPanel>
</StackPanel>
</ScrollViewer>
</Page>

263
Pages/ProgressPage.xaml.cs Normal file
Fájl megtekintése

@@ -0,0 +1,263 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using InstaSoftOfficeTool.Models;
using InstaSoftOfficeTool.Services;
namespace InstaSoftOfficeTool.Pages
{
public partial class ProgressPage : Page
{
private readonly MainWindow _main;
private readonly InstallConfig _config;
public ProgressPage(MainWindow main, InstallConfig config)
{
InitializeComponent();
_main = main;
_config = config;
}
public async void StartInstallation()
{
try
{
// Step 1: Download ODT
SetStepActive(Step1Icon, Step1Text);
AppendLog("ODT let\u00f6lt\u00e9se indul...");
var downloader = new OdtDownloader();
downloader.StatusChanged += msg => Dispatcher.Invoke(() => AppendLog(msg));
bool downloaded = await downloader.DownloadAndExtractAsync();
if (!downloaded)
{
SetStepError(Step1Icon, Step1Text);
ShowDone(false, "Az ODT let\u00f6lt\u00e9se sikertelen.");
return;
}
SetStepDone(Step1Icon, Step1Text);
// Step 2: Generate config XML
SetStepActive(Step2Icon, Step2Text);
AppendLog("Konfigur\u00e1ci\u00f3s XML gener\u00e1l\u00e1sa...");
string xml = OdtXmlGenerator.Generate(_config);
string xmlPath = Path.Combine(downloader.OdtFolder, "configuration.xml");
File.WriteAllText(xmlPath, xml);
AppendLog("XML mentve: " + xmlPath);
SetStepDone(Step2Icon, Step2Text);
// Step 3: Run setup.exe /configure
SetStepActive(Step3Icon, Step3Text);
AppendLog("Office telep\u00edt\u00e9s ind\u00edt\u00e1sa...");
AppendLog("setup.exe /configure \"" + xmlPath + "\"");
int exitCode = await downloader.RunSetupAsync(xmlPath, msg =>
Dispatcher.Invoke(() => AppendLog(msg)));
if (exitCode == 0)
{
SetStepDone(Step3Icon, Step3Text);
ShowDone(true, "Az Office sikeresen telep\u00fclt!");
}
else
{
SetStepError(Step3Icon, Step3Text);
ShowDone(false, "A telep\u00edt\u00e9s hibak\u00f3ddal fejez\u0151d\u00f6tt be: " + exitCode);
}
}
catch (Exception ex)
{
AppendLog("HIBA: " + ex.Message);
ShowDone(false, "V\u00e1ratlan hiba t\u00f6rt\u00e9nt.");
}
}
private void AppendLog(string text)
{
LogText.Text += DateTime.Now.ToString("HH:mm:ss") + " " + text + "\n";
LogText.ScrollToEnd();
}
private void SetStepActive(TextBlock icon, TextBlock text)
{
Dispatcher.Invoke(() =>
{
icon.Text = "\uE72A";
icon.Foreground = (Brush)FindResource("AccentBrush");
text.Foreground = (Brush)FindResource("TextPrimaryBrush");
text.FontWeight = FontWeights.SemiBold;
});
}
private void SetStepDone(TextBlock icon, TextBlock text)
{
Dispatcher.Invoke(() =>
{
icon.Text = "\uE73E";
icon.Foreground = (Brush)FindResource("SuccessBrush");
text.Foreground = (Brush)FindResource("SuccessBrush");
text.FontWeight = FontWeights.Normal;
});
}
private void SetStepError(TextBlock icon, TextBlock text)
{
Dispatcher.Invoke(() =>
{
icon.Text = "\uE711";
icon.Foreground = (Brush)FindResource("ErrorBrush");
text.Foreground = (Brush)FindResource("ErrorBrush");
text.FontWeight = FontWeights.Normal;
});
}
private void ShowDone(bool success, string message)
{
Dispatcher.Invoke(() =>
{
MainProgress.IsIndeterminate = false;
MainProgress.Value = 100;
TitleText.Text = success ? "Telep\u00edt\u00e9s befejezve" : "Telep\u00edt\u00e9s sikertelen";
DoneIcon.Text = success ? "\uE73E" : "\uE711";
DoneIcon.Foreground = success
? (Brush)FindResource("SuccessBrush")
: (Brush)FindResource("ErrorBrush");
DoneText.Text = message;
DoneText.Foreground = DoneIcon.Foreground;
DonePanel.Visibility = Visibility.Visible;
if (success)
{
// Show activate card if no product key was provided
if (string.IsNullOrEmpty(_config.ProductKey))
{
ActivateCard.Visibility = Visibility.Visible;
}
// Show launch buttons
BuildLaunchButtons();
LaunchCard.Visibility = Visibility.Visible;
}
_main.ShowCloseButton();
});
}
private void BuildLaunchButtons()
{
LaunchButtons.Children.Clear();
var apps = new[]
{
("Word", "WINWORD.EXE"),
("Excel", "EXCEL.EXE"),
("PowerPoint", "POWERPNT.EXE"),
("Outlook", "OUTLOOK.EXE"),
};
foreach (var (name, exe) in apps)
{
// Skip if excluded
if (_config.ExcludedApps.Contains(name == "Word" ? "Word" :
name == "Excel" ? "Excel" :
name == "PowerPoint" ? "PowerPoint" :
name == "Outlook" ? "Outlook" : ""))
continue;
var btn = new Button
{
Content = name,
Style = (Style)FindResource("SecondaryButton"),
Padding = new Thickness(18, 8, 18, 8),
FontSize = 13,
Margin = new Thickness(0, 0, 8, 0),
Tag = exe
};
btn.Click += LaunchApp_Click;
LaunchButtons.Children.Add(btn);
}
}
private void LaunchApp_Click(object sender, RoutedEventArgs e)
{
var btn = (Button)sender;
var exe = (string)btn.Tag;
try
{
// Try common Office paths
var paths = new[]
{
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
"Microsoft Office", "root", "Office16", exe),
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
"Microsoft Office", "root", "Office16", exe),
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
"Microsoft Office", "Office16", exe),
};
foreach (var path in paths)
{
if (File.Exists(path))
{
Process.Start(path);
return;
}
}
// Fallback: let Windows find it
Process.Start(exe);
}
catch
{
AppendLog("Nem siker\u00fclt elind\u00edtani: " + exe);
}
}
private async void BtnActivateNow_Click(object sender, RoutedEventArgs e)
{
string key = await _main.AskProductKeyAsync();
if (string.IsNullOrEmpty(key)) return;
BtnActivateNow.IsEnabled = false;
BtnActivateNow.Content = "Aktiv\u00e1l\u00e1s...";
var lm = new LicenseManager();
if (!lm.FindOspp())
{
AppendLog("Az ospp.vbs nem tal\u00e1lhat\u00f3.");
BtnActivateNow.IsEnabled = true;
BtnActivateNow.Content = "Aktiv\u00e1l\u00e1s";
return;
}
AppendLog("Term\u00e9kkulcs telep\u00edt\u00e9se: " + key);
string inpResult = await lm.InstallKeyAsync(key);
AppendLog(inpResult);
AppendLog("Aktiv\u00e1l\u00e1s...");
string actResult = await lm.ActivateAsync();
AppendLog(actResult);
if (actResult.Contains("successful") || actResult.Contains("sikeres"))
{
BtnActivateNow.Content = "Aktiv\u00e1lva \u2713";
AppendLog("Az Office sikeresen aktiv\u00e1lva!");
}
else
{
BtnActivateNow.IsEnabled = true;
BtnActivateNow.Content = "Aktiv\u00e1l\u00e1s";
AppendLog("Az aktiv\u00e1l\u00e1s eredm\u00e9ny\u00e9t ellen\u0151rizze a kimenetben.");
}
}
}
}

52
Pages/RemovePage.xaml Normal file
Fájl megtekintése

@@ -0,0 +1,52 @@
<Page x:Class="InstaSoftOfficeTool.Pages.RemovePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent">
<Grid Margin="40,30">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="0,0,0,20">
<TextBlock Text="Office eltávolítás" FontSize="24" FontWeight="Light"/>
<TextBlock Text="A számítógépen talált Office telepítések:"
FontSize="14" Foreground="{StaticResource TextSecondaryBrush}" Margin="0,4,0,0"/>
</StackPanel>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<StackPanel>
<StackPanel x:Name="OfficeListPanel"/>
<TextBlock x:Name="NoOfficeText" Text="Nem található telepített Office."
FontSize="14" Foreground="{StaticResource TextSecondaryBrush}"
Margin="0,20,0,0" Visibility="Collapsed"/>
<Border x:Name="LicenseCleanupPanel" Margin="0,20,0,0"
Background="{StaticResource CardBrush}" CornerRadius="8"
BorderBrush="{StaticResource BorderBrush}" BorderThickness="1"
Padding="16,12">
<CheckBox x:Name="CbCleanLicense" Style="{StaticResource FluentCheckBox}"
Content="Licenc-adatbázis tisztítása is (ajánlott)"
IsChecked="True"/>
</Border>
<Border x:Name="LogPanel" Margin="0,16,0,0" Background="#F8F8F8"
CornerRadius="6" Padding="12" Visibility="Collapsed"
BorderBrush="{StaticResource BorderBrush}" BorderThickness="1">
<TextBox x:Name="LogText" FontFamily="Consolas" FontSize="11"
TextWrapping="Wrap" Foreground="{StaticResource TextSecondaryBrush}"
IsReadOnly="True" Background="Transparent" BorderThickness="0"
VerticalScrollBarVisibility="Auto" AcceptsReturn="True" MaxHeight="200"/>
</Border>
</StackPanel>
</ScrollViewer>
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,12,0,0">
<Button x:Name="BtnRemove" Content="Eltávolítás" Style="{StaticResource PrimaryButton}"
Click="BtnRemove_Click"/>
</StackPanel>
</Grid>
</Page>

170
Pages/RemovePage.xaml.cs Normal file
Fájl megtekintése

@@ -0,0 +1,170 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using InstaSoftOfficeTool.Models;
using InstaSoftOfficeTool.Services;
namespace InstaSoftOfficeTool.Pages
{
public partial class RemovePage : Page
{
private readonly MainWindow _main;
private List<InstalledOffice> _detected;
public RemovePage(MainWindow main)
{
InitializeComponent();
_main = main;
Loaded += (s, e) => DetectOffice();
}
private void DetectOffice()
{
_detected = OfficeDetector.Detect();
OfficeListPanel.Children.Clear();
if (_detected.Count == 0)
{
NoOfficeText.Visibility = Visibility.Visible;
LicenseCleanupPanel.Visibility = Visibility.Collapsed;
BtnRemove.IsEnabled = false;
return;
}
foreach (var office in _detected)
{
var cb = new CheckBox
{
Content = office.DisplayName + (string.IsNullOrEmpty(office.Version) ? "" : " (" + office.Version + ")"),
IsChecked = true,
Style = (Style)FindResource("FluentCheckBox"),
Tag = office,
Margin = new Thickness(0, 4, 0, 4),
FontSize = 14
};
OfficeListPanel.Children.Add(cb);
}
}
private async void BtnRemove_Click(object sender, RoutedEventArgs e)
{
bool confirmed = await _main.ConfirmAsync(
"Office elt\u00e1vol\u00edt\u00e1s",
"Biztosan el szeretn\u00e9 t\u00e1vol\u00edtani a kiv\u00e1lasztott Office telep\u00edt\u00e9seket?",
"Elt\u00e1vol\u00edt\u00e1s", "M\u00e9gse");
if (!confirmed) return;
BtnRemove.IsEnabled = false;
LogPanel.Visibility = Visibility.Visible;
try
{
var c2rProducts = new System.Collections.Generic.List<string>();
foreach (UIElement child in OfficeListPanel.Children)
{
if (child is CheckBox cb && cb.IsChecked == true)
{
var office = (InstalledOffice)cb.Tag;
if (office.IsClickToRun)
{
c2rProducts.Add(office.ProductCode);
}
else if (!string.IsNullOrEmpty(office.ProductCode))
{
AppendLog("MSI elt\u00e1vol\u00edt\u00e1s: " + office.DisplayName);
var runner = new ProcessRunner();
runner.OutputReceived += msg => Dispatcher.Invoke(() => AppendLog(msg));
int code = await runner.RunAsync("msiexec", "/x " + office.ProductCode + " /qb");
AppendLog("MSI exit code: " + code);
}
}
}
if (c2rProducts.Count > 0)
{
AppendLog("Click-to-Run term\u00e9kek elt\u00e1vol\u00edt\u00e1sa: " + string.Join(", ", c2rProducts));
var downloader = new OdtDownloader();
downloader.StatusChanged += msg => Dispatcher.Invoke(() => AppendLog(msg));
bool ok = await downloader.DownloadAndExtractAsync();
if (!ok)
{
AppendLog("HIBA: Az ODT let\u00f6lt\u00e9se sikertelen.");
BtnRemove.IsEnabled = true;
return;
}
string removeXml = OdtXmlGenerator.GenerateRemoveProducts(c2rProducts.ToArray());
string xmlPath = Path.Combine(downloader.OdtFolder, "remove.xml");
File.WriteAllText(xmlPath, removeXml);
AppendLog("Remove XML:");
AppendLog(removeXml);
AppendLog("");
AppendLog("Futtat\u00e1s: setup.exe /configure remove.xml");
AppendLog("Ez eltarthat n\u00e9h\u00e1ny percig...");
int exitCode = await downloader.RunRemoveAsync(xmlPath,
msg => Dispatcher.Invoke(() => AppendLog(msg)));
AppendLog("setup.exe exit code: " + exitCode);
if (exitCode == 0)
{
AppendLog("Office sikeresen elt\u00e1vol\u00edtva.");
}
else
{
AppendLog("FIGYELEM: Az elt\u00e1vol\u00edt\u00e1s nem siker\u00fclt (k\u00f3d: " + exitCode + ")");
AppendLog("Pr\u00f3b\u00e1lja meg manu\u00e1lisan: Vez\u00e9rl\u0151pult > Programok elt\u00e1vol\u00edt\u00e1sa");
}
}
if (CbCleanLicense.IsChecked == true)
{
AppendLog("");
AppendLog("Licenc-adatb\u00e1zis tiszt\u00edt\u00e1sa...");
var lm = new LicenseManager();
if (lm.FindOspp())
{
var cleanResult = await lm.RemoveAllKeysAsync();
AppendLog(cleanResult);
}
else
{
AppendLog("Az ospp.vbs nem tal\u00e1lhat\u00f3 \u2014 licenc-tiszt\u00edt\u00e1s kihagyva.");
}
}
AppendLog("");
AppendLog("K\u00e9sz. Lista friss\u00edt\u00e9se...");
DetectOffice();
if (_detected.Count == 0)
{
AppendLog("Nincs t\u00f6bb telep\u00edtett Office.");
}
}
catch (Exception ex)
{
AppendLog("V\u00e1ratlan hiba: " + ex.Message);
AppendLog(ex.StackTrace);
}
BtnRemove.IsEnabled = _detected.Count > 0;
_main.ShowCloseButton();
}
private void AppendLog(string text)
{
LogText.Text += DateTime.Now.ToString("HH:mm:ss") + " " + text + "\n";
LogText.ScrollToEnd();
}
}
}

63
Pages/SummaryPage.xaml Normal file
Fájl megtekintése

@@ -0,0 +1,63 @@
<Page x:Class="InstaSoftOfficeTool.Pages.SummaryPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent">
<ScrollViewer VerticalScrollBarVisibility="Auto" Margin="40,30">
<StackPanel>
<TextBlock Text="Összegzés" FontSize="24" FontWeight="Light" Margin="0,0,0,20"/>
<TextBlock Text="Ellenőrizze a beállításokat a telepítés indítása előtt."
FontSize="14" Foreground="{StaticResource TextSecondaryBrush}" Margin="0,0,0,16"/>
<Border Background="{StaticResource CardBrush}" CornerRadius="8"
BorderBrush="{StaticResource BorderBrush}" BorderThickness="1"
Padding="20,16" Margin="0,0,0,16">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Verzió:" FontWeight="SemiBold" Margin="0,4"/>
<TextBlock Grid.Row="0" Grid.Column="1" x:Name="SumVersion" Margin="0,4"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Kiadás:" FontWeight="SemiBold" Margin="0,4"/>
<TextBlock Grid.Row="1" Grid.Column="1" x:Name="SumEdition" Margin="0,4"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="Architektúra:" FontWeight="SemiBold" Margin="0,4"/>
<TextBlock Grid.Row="2" Grid.Column="1" x:Name="SumArch" Margin="0,4"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="Nyelv:" FontWeight="SemiBold" Margin="0,4"/>
<TextBlock Grid.Row="3" Grid.Column="1" x:Name="SumLanguage" Margin="0,4"/>
<TextBlock Grid.Row="4" Grid.Column="0" Text="Termékkulcs:" FontWeight="SemiBold" Margin="0,4"/>
<TextBlock Grid.Row="4" Grid.Column="1" x:Name="SumKey" Margin="0,4"/>
<TextBlock Grid.Row="5" Grid.Column="0" Text="Kizárt alkalmazások:" FontWeight="SemiBold" Margin="0,4"/>
<TextBlock Grid.Row="5" Grid.Column="1" x:Name="SumExcluded" Margin="0,4" TextWrapping="Wrap"/>
</Grid>
</Border>
<Expander Header="Konfigurációs XML megtekintése" FontSize="13" Margin="0,0,0,10">
<Border Background="#F8F8F8" CornerRadius="4" Padding="12" Margin="0,8,0,0"
BorderBrush="{StaticResource BorderBrush}" BorderThickness="1">
<TextBox x:Name="XmlPreview" IsReadOnly="True" TextWrapping="Wrap"
FontFamily="Consolas" FontSize="12" BorderThickness="0"
Background="Transparent" VerticalScrollBarVisibility="Auto"
MaxHeight="200"/>
</Border>
</Expander>
<Button x:Name="BtnSaveXml" Content="XML mentése fájlba..." Style="{StaticResource SecondaryButton}"
HorizontalAlignment="Left" Click="BtnSaveXml_Click" Margin="0,4,0,0"/>
</StackPanel>
</ScrollViewer>
</Page>

63
Pages/SummaryPage.xaml.cs Normal file
Fájl megtekintése

@@ -0,0 +1,63 @@
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using InstaSoftOfficeTool.Models;
using InstaSoftOfficeTool.Services;
using Microsoft.Win32;
namespace InstaSoftOfficeTool.Pages
{
public partial class SummaryPage : Page, IWizardPage
{
private readonly MainWindow _main;
private readonly InstallConfig _config;
private string _generatedXml;
public SummaryPage(MainWindow main, InstallConfig config)
{
InitializeComponent();
_main = main;
_config = config;
Loaded += (s, e) => RefreshSummary();
}
private void RefreshSummary()
{
SumVersion.Text = _config.GetVersionDisplayName();
SumEdition.Text = _config.Edition?.DisplayName ?? "-";
SumArch.Text = _config.Architecture + "-bit";
SumLanguage.Text = _config.GetLanguageDisplayName() + " (" + _config.Language + ")";
SumKey.Text = string.IsNullOrEmpty(_config.ProductKey) ? "Nincs megadva" : _config.ProductKey;
if (_config.ExcludedApps.Count > 0)
SumExcluded.Text = string.Join(", ", _config.ExcludedApps);
else
SumExcluded.Text = "Nincs (minden alkalmaz\u00e1s telep\u00fcl)";
_generatedXml = OdtXmlGenerator.Generate(_config);
XmlPreview.Text = _generatedXml;
}
private void BtnSaveXml_Click(object sender, RoutedEventArgs e)
{
var dlg = new SaveFileDialog
{
Filter = "XML f\u00e1jl (*.xml)|*.xml",
FileName = "configuration.xml"
};
if (dlg.ShowDialog() == true)
{
System.IO.File.WriteAllText(dlg.FileName, _generatedXml);
MessageBox.Show("XML sikeresen mentve:\n" + dlg.FileName,
"Ment\u00e9s", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
public bool Validate()
{
return true;
}
}
}

Fájl megtekintése

@@ -0,0 +1,51 @@
<Page x:Class="InstaSoftOfficeTool.Pages.TroubleshootPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent">
<Grid Margin="40,30">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Title -->
<StackPanel Grid.Row="0" Margin="0,0,0,16">
<TextBlock Text="Licenc-kezelés" FontSize="24" FontWeight="Light"/>
<TextBlock Text="Office licenc állapot lekérdezése, aktiválás és termékkulcsok kezelése"
FontSize="14" Foreground="{StaticResource TextSecondaryBrush}" Margin="0,4,0,0"/>
</StackPanel>
<!-- Key cards (scrollable) -->
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" Margin="0,0,0,8">
<StackPanel x:Name="KeyCardsPanel"/>
</ScrollViewer>
<!-- Details expander -->
<Expander x:Name="DetailsExpander" Grid.Row="2" Header="Részletek" FontSize="13"
Margin="0,0,0,8" Expanded="DetailsExpander_Expanded" Collapsed="DetailsExpander_Collapsed">
<StackPanel Margin="0,8,0,0">
<TextBlock x:Name="OsppPathText" FontSize="12"
Foreground="{StaticResource TextSecondaryBrush}" Margin="0,0,0,6"/>
<Border Background="#F8F8F8" CornerRadius="4" Padding="10"
BorderBrush="{StaticResource BorderBrush}" BorderThickness="1">
<TextBox x:Name="OutputText" FontFamily="Consolas" FontSize="11"
TextWrapping="Wrap" Foreground="{StaticResource TextSecondaryBrush}"
IsReadOnly="True" Background="Transparent" BorderThickness="0"
VerticalScrollBarVisibility="Auto" AcceptsReturn="True"
Height="85"/>
</Border>
</StackPanel>
</Expander>
<!-- Buttons -->
<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,4,0,0">
<Button x:Name="BtnRefresh" Content="Állapot frissítése" Style="{StaticResource SecondaryButton}"
Click="BtnRefresh_Click" Margin="0,0,8,0"/>
<Button x:Name="BtnRemoveAll" Content="Összes kulcs eltávolítása" Style="{StaticResource PrimaryButton}"
Click="BtnRemoveAll_Click" IsEnabled="False" Visibility="Collapsed"/>
</StackPanel>
</Grid>
</Page>

Fájl megtekintése

@@ -0,0 +1,311 @@
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using InstaSoftOfficeTool.Services;
namespace InstaSoftOfficeTool.Pages
{
public partial class TroubleshootPage : Page
{
private readonly MainWindow _main;
private readonly LicenseManager _licenseManager = new LicenseManager();
private List<LicenseEntry> _entries = new List<LicenseEntry>();
public TroubleshootPage(MainWindow main)
{
InitializeComponent();
_main = main;
Loaded += async (s, e) => await RefreshStatus();
}
private async System.Threading.Tasks.Task RefreshStatus()
{
OutputText.Text = "";
OsppPathText.Text = "";
KeyCardsPanel.Children.Clear();
BtnRemoveAll.IsEnabled = false;
BtnRemoveAll.Visibility = Visibility.Collapsed;
BtnRefresh.IsEnabled = false;
var loadingText = new TextBlock
{
Text = "Keres\u00e9s folyamatban...",
FontSize = 13,
Foreground = (Brush)FindResource("TextSecondaryBrush"),
Margin = new Thickness(0, 8, 0, 8)
};
KeyCardsPanel.Children.Add(loadingText);
bool found = _licenseManager.FindOspp();
if (!found)
{
KeyCardsPanel.Children.Clear();
var errorCard = new Border
{
Background = (Brush)FindResource("CardBrush"),
BorderBrush = (Brush)FindResource("BorderBrush"),
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(8),
Padding = new Thickness(16, 14, 16, 14),
Margin = new Thickness(0, 0, 0, 6)
};
var errorPanel = new StackPanel();
errorPanel.Children.Add(new TextBlock
{
Text = "Az ospp.vbs nem tal\u00e1lhat\u00f3",
FontSize = 14, FontWeight = FontWeights.SemiBold,
Foreground = (Brush)FindResource("ErrorBrush")
});
errorPanel.Children.Add(new TextBlock
{
Text = "Nincs telep\u00edtett Microsoft Office, vagy nem a szok\u00e1sos helyre lett telep\u00edtve.",
FontSize = 12, Foreground = (Brush)FindResource("TextSecondaryBrush"),
TextWrapping = TextWrapping.Wrap, Margin = new Thickness(0, 4, 0, 0)
});
errorCard.Child = errorPanel;
KeyCardsPanel.Children.Add(errorCard);
BtnRefresh.IsEnabled = true;
return;
}
OsppPathText.Text = "ospp.vbs helye: " + _licenseManager.OsppPath;
try
{
string status = await _licenseManager.GetStatusAsync();
OutputText.Text = status;
_entries = _licenseManager.ParseLicenseEntries(status);
BuildKeyCards();
}
catch (Exception ex)
{
KeyCardsPanel.Children.Clear();
OutputText.Text = "Hiba a lek\u00e9rdez\u00e9s sor\u00e1n: " + ex.Message;
}
BtnRefresh.IsEnabled = true;
}
private void BuildKeyCards()
{
KeyCardsPanel.Children.Clear();
if (_entries.Count == 0)
{
var noKeyCard = new Border
{
Background = (Brush)FindResource("CardBrush"),
BorderBrush = (Brush)FindResource("BorderBrush"),
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(8),
Padding = new Thickness(16, 14, 16, 14)
};
noKeyCard.Child = new TextBlock
{
Text = "Nincs telep\u00edtett term\u00e9kkulcs.",
FontSize = 13,
Foreground = (Brush)FindResource("TextSecondaryBrush")
};
KeyCardsPanel.Children.Add(noKeyCard);
return;
}
if (_entries.Count > 1)
{
BtnRemoveAll.Visibility = Visibility.Visible;
BtnRemoveAll.IsEnabled = true;
}
foreach (var entry in _entries)
{
KeyCardsPanel.Children.Add(CreateKeyCard(entry));
}
}
private Border CreateKeyCard(LicenseEntry entry)
{
var grid = new Grid();
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
var infoPanel = new StackPanel { VerticalAlignment = VerticalAlignment.Center };
infoPanel.Children.Add(new TextBlock
{
Text = string.IsNullOrEmpty(entry.LicenseName) ? "Ismeretlen licenc" : entry.LicenseName,
FontSize = 13, FontWeight = FontWeights.SemiBold,
TextTrimming = TextTrimming.CharacterEllipsis
});
var statusLine = !string.IsNullOrEmpty(entry.ErrorDescription)
? entry.ErrorDescription
: (!string.IsNullOrEmpty(entry.Status) ? entry.Status : entry.Description);
infoPanel.Children.Add(new TextBlock
{
Text = statusLine,
FontSize = 11, Foreground = (Brush)FindResource("TextSecondaryBrush"),
TextTrimming = TextTrimming.CharacterEllipsis
});
infoPanel.Children.Add(new TextBlock
{
Text = "Kulcs: *****-" + entry.Last5,
FontSize = 11, FontFamily = new FontFamily("Consolas"),
Foreground = (Brush)FindResource("TextSecondaryBrush"),
Margin = new Thickness(0, 2, 0, 0)
});
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,
Tag = entry.Last5,
Margin = new Thickness(6, 0, 0, 0)
};
removeBtn.Click += BtnRemoveSingle_Click;
btnPanel.Children.Add(removeBtn);
Grid.SetColumn(btnPanel, 1);
grid.Children.Add(btnPanel);
return new Border
{
Background = (Brush)FindResource("CardBrush"),
BorderBrush = (Brush)FindResource("BorderBrush"),
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(8),
Padding = new Thickness(16, 10, 16, 10),
Margin = new Thickness(0, 0, 0, 6),
Child = grid
};
}
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;
var last5 = (string)btn.Tag;
bool confirmed = await _main.ConfirmAsync(
"Kulcs elt\u00e1vol\u00edt\u00e1sa",
"Biztosan el szeretn\u00e9 t\u00e1vol\u00edtani a *****-" + last5 + " kulcsot?",
"Elt\u00e1vol\u00edt\u00e1s", "M\u00e9gse", DialogType.Question);
if (!confirmed) return;
btn.IsEnabled = false;
btn.Content = "...";
try
{
await _licenseManager.RemoveKeyAsync(last5);
await RefreshStatus();
}
catch (Exception ex)
{
OutputText.Text += "\nHiba: " + ex.Message;
btn.IsEnabled = true;
btn.Content = "Elt\u00e1vol\u00edt\u00e1s";
}
}
private async void BtnRefresh_Click(object sender, RoutedEventArgs e)
{
await RefreshStatus();
}
private async void BtnRemoveAll_Click(object sender, RoutedEventArgs e)
{
bool confirmed = await _main.ConfirmAsync(
"\u00d6sszes kulcs elt\u00e1vol\u00edt\u00e1sa",
"Biztosan el szeretn\u00e9 t\u00e1vol\u00edtani az \u00f6sszes telep\u00edtett term\u00e9kkulcsot (" + _entries.Count + " db)?\n\n" +
"Ez nem t\u00f6r\u00f6l adatot, csak az aktiv\u00e1ci\u00f3s \u00e1llapotot \u00e1ll\u00edtja vissza.",
"\u00d6sszes elt\u00e1vol\u00edt\u00e1sa", "M\u00e9gse");
if (!confirmed) return;
BtnRemoveAll.IsEnabled = false;
BtnRefresh.IsEnabled = false;
try
{
await _licenseManager.RemoveAllKeysAsync();
await RefreshStatus();
}
catch (Exception ex)
{
OutputText.Text += "\nHiba: " + ex.Message;
}
BtnRefresh.IsEnabled = true;
}
private void DetailsExpander_Expanded(object sender, RoutedEventArgs e)
{
_main.Height = 680;
}
private void DetailsExpander_Collapsed(object sender, RoutedEventArgs e)
{
_main.Height = 550;
}
}
}

47
Pages/VersionPage.xaml Normal file
Fájl megtekintése

@@ -0,0 +1,47 @@
<Page x:Class="InstaSoftOfficeTool.Pages.VersionPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent">
<Grid Margin="40,30">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="0,0,0,24">
<TextBlock Text="Válasszon Office verziót" FontSize="24" FontWeight="Light"/>
<TextBlock Text="Melyik évjáratot szeretné telepíteni?" FontSize="14"
Foreground="{StaticResource TextSecondaryBrush}" Margin="0,4,0,0"/>
</StackPanel>
<StackPanel Grid.Row="1" VerticalAlignment="Top">
<RadioButton x:Name="Rb2024" Style="{StaticResource CardRadioButton}"
GroupName="Version" IsChecked="True" Margin="0,0,0,10">
<StackPanel Margin="8,2">
<TextBlock Text="Office 2024" FontSize="18" FontWeight="SemiBold"/>
<TextBlock Text="2024. októberi kiadás · Windows 10 / 11"
FontSize="12" Foreground="{StaticResource TextSecondaryBrush}" Margin="0,2,0,0"/>
</StackPanel>
</RadioButton>
<RadioButton x:Name="Rb2021" Style="{StaticResource CardRadioButton}"
GroupName="Version" Margin="0,0,0,10">
<StackPanel Margin="8,2">
<TextBlock Text="Office 2021" FontSize="18" FontWeight="SemiBold"/>
<TextBlock Text="2021. októberi kiadás · Windows 10 / 11"
FontSize="12" Foreground="{StaticResource TextSecondaryBrush}" Margin="0,2,0,0"/>
</StackPanel>
</RadioButton>
<RadioButton x:Name="Rb2019" Style="{StaticResource CardRadioButton}"
GroupName="Version" Margin="0,0,0,10">
<StackPanel Margin="8,2">
<TextBlock Text="Office 2019" FontSize="18" FontWeight="SemiBold"/>
<TextBlock Text="2019. szeptemberi kiadás · Windows 7 / 8.1 / 10 / 11 · Támogatás lejárt: 2025.10."
FontSize="12" Foreground="{StaticResource TextSecondaryBrush}" Margin="0,2,0,0"/>
</StackPanel>
</RadioButton>
</StackPanel>
</Grid>
</Page>

34
Pages/VersionPage.xaml.cs Normal file
Fájl megtekintése

@@ -0,0 +1,34 @@
using System.Windows.Controls;
using InstaSoftOfficeTool.Models;
namespace InstaSoftOfficeTool.Pages
{
public partial class VersionPage : Page, IWizardPage
{
private readonly MainWindow _main;
private readonly InstallConfig _config;
public VersionPage(MainWindow main, InstallConfig config)
{
InitializeComponent();
_main = main;
_config = config;
// Restore selection
switch (_config.Version)
{
case OfficeVersion.Office2024: Rb2024.IsChecked = true; break;
case OfficeVersion.Office2021: Rb2021.IsChecked = true; break;
case OfficeVersion.Office2019: Rb2019.IsChecked = true; break;
}
}
public bool Validate()
{
if (Rb2024.IsChecked == true) _config.Version = OfficeVersion.Office2024;
else if (Rb2021.IsChecked == true) _config.Version = OfficeVersion.Office2021;
else if (Rb2019.IsChecked == true) _config.Version = OfficeVersion.Office2019;
return true;
}
}
}

59
Pages/WelcomePage.xaml Normal file
Fájl megtekintése

@@ -0,0 +1,59 @@
<Page x:Class="InstaSoftOfficeTool.Pages.WelcomePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="Transparent">
<Grid Margin="40,30">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="0,0,0,30">
<TextBlock Text="Üdvözöljük!" FontSize="28" FontWeight="Light"
Foreground="{StaticResource TextPrimaryBrush}"/>
<TextBlock Text="Válassza ki a kívánt műveletet:" FontSize="15"
Foreground="{StaticResource TextSecondaryBrush}" Margin="0,4,0,0"/>
</StackPanel>
<UniformGrid Grid.Row="1" Columns="3" Margin="0,0,0,0">
<Button Style="{StaticResource CardButton}" Margin="0,0,10,0"
Click="InstallClick">
<StackPanel>
<TextBlock FontSize="28" Text="&#xE710;" FontFamily="Segoe MDL2 Assets"
Foreground="{StaticResource AccentBrush}" Margin="0,0,0,12"/>
<TextBlock Text="Office telepítés" FontSize="16" FontWeight="SemiBold"/>
<TextBlock Text="Új Microsoft Office telepítése a számítógépre"
FontSize="12" Foreground="{StaticResource TextSecondaryBrush}"
TextWrapping="Wrap" Margin="0,6,0,0"/>
</StackPanel>
</Button>
<Button Style="{StaticResource CardButton}" Margin="5,0,5,0"
Click="RemoveClick">
<StackPanel>
<TextBlock FontSize="28" Text="&#xE74D;" FontFamily="Segoe MDL2 Assets"
Foreground="{StaticResource WarningBrush}" Margin="0,0,0,12"/>
<TextBlock Text="Office eltávolítás" FontSize="16" FontWeight="SemiBold"/>
<TextBlock Text="Meglévő Microsoft Office eltávolítása"
FontSize="12" Foreground="{StaticResource TextSecondaryBrush}"
TextWrapping="Wrap" Margin="0,6,0,0"/>
</StackPanel>
</Button>
<Button Style="{StaticResource CardButton}" Margin="10,0,0,0"
Click="LicenseClick">
<StackPanel>
<TextBlock FontSize="28" Text="&#xE8D7;" FontFamily="Segoe MDL2 Assets"
Foreground="{StaticResource SuccessBrush}" Margin="0,0,0,12"/>
<TextBlock Text="Licenc-kezelés" FontSize="16" FontWeight="SemiBold"/>
<TextBlock Text="Licenc állapot lekérdezése, termékkulcsok törlése"
FontSize="12" Foreground="{StaticResource TextSecondaryBrush}"
TextWrapping="Wrap" Margin="0,6,0,0"/>
</StackPanel>
</Button>
</UniformGrid>
</Grid>
</Page>

31
Pages/WelcomePage.xaml.cs Normal file
Fájl megtekintése

@@ -0,0 +1,31 @@
using System.Windows;
using System.Windows.Controls;
namespace InstaSoftOfficeTool.Pages
{
public partial class WelcomePage : Page
{
private readonly MainWindow _main;
public WelcomePage(MainWindow main)
{
InitializeComponent();
_main = main;
}
private void InstallClick(object sender, RoutedEventArgs e)
{
_main.StartInstallFlow();
}
private void RemoveClick(object sender, RoutedEventArgs e)
{
_main.StartRemoveFlow();
}
private void LicenseClick(object sender, RoutedEventArgs e)
{
_main.StartLicenseFlow();
}
}
}