v1.07 — Pre-install Office check before installation
- New PreInstallCheckPage between Summary and Progress - Detects existing Office installs, offers removal before new install - License cleanup option included - Skip button to proceed without removal - Auto-proceeds to install after removal completes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,9 +9,9 @@
|
|||||||
<Company>InstaSoft Zrt.</Company>
|
<Company>InstaSoft Zrt.</Company>
|
||||||
<Product>InstaSoft Office Tool</Product>
|
<Product>InstaSoft Office Tool</Product>
|
||||||
<Copyright>Copyright (c) InstaSoft Zrt. 2026</Copyright>
|
<Copyright>Copyright (c) InstaSoft Zrt. 2026</Copyright>
|
||||||
<Version>1.0.6</Version>
|
<Version>1.0.7</Version>
|
||||||
<AssemblyVersion>1.0.6.0</AssemblyVersion>
|
<AssemblyVersion>1.0.7.0</AssemblyVersion>
|
||||||
<FileVersion>1.0.6.0</FileVersion>
|
<FileVersion>1.0.7.0</FileVersion>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
Foreground="{StaticResource TextSecondaryBrush}" Margin="0,-2,0,0"/>
|
Foreground="{StaticResource TextSecondaryBrush}" Margin="0,-2,0,0"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<TextBlock Text="v1.06" HorizontalAlignment="Right" VerticalAlignment="Center"
|
<TextBlock Text="v1.07" HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||||
FontSize="12" Foreground="{StaticResource TextSecondaryBrush}"/>
|
FontSize="12" Foreground="{StaticResource TextSecondaryBrush}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
|
|||||||
@@ -38,12 +38,13 @@ namespace InstaSoftOfficeTool
|
|||||||
_config = new InstallConfig();
|
_config = new InstallConfig();
|
||||||
_wizardPages = new List<Page>
|
_wizardPages = new List<Page>
|
||||||
{
|
{
|
||||||
new VersionPage(this, _config),
|
new VersionPage(this, _config), // 0
|
||||||
new EditionPage(this, _config),
|
new EditionPage(this, _config), // 1
|
||||||
new ConfigPage(this, _config),
|
new ConfigPage(this, _config), // 2
|
||||||
new ProductKeyPage(this, _config),
|
new ProductKeyPage(this, _config), // 3
|
||||||
new SummaryPage(this, _config),
|
new SummaryPage(this, _config), // 4
|
||||||
new ProgressPage(this, _config)
|
new PreInstallCheckPage(this), // 5 — remove old Office
|
||||||
|
new ProgressPage(this, _config) // 6
|
||||||
};
|
};
|
||||||
_currentPageIndex = 0;
|
_currentPageIndex = 0;
|
||||||
ShowCurrentPage();
|
ShowCurrentPage();
|
||||||
@@ -91,8 +92,8 @@ namespace InstaSoftOfficeTool
|
|||||||
StepIndicator.Children.Clear();
|
StepIndicator.Children.Clear();
|
||||||
if (_currentFlow != "install") return;
|
if (_currentFlow != "install") return;
|
||||||
|
|
||||||
// Only show dots for install flow (6 steps, but last is progress - no dot)
|
// Only show dots for install flow (exclude PreInstallCheck + Progress)
|
||||||
int totalDots = _wizardPages.Count - 1; // exclude progress page
|
int totalDots = _wizardPages.Count - 2;
|
||||||
for (int i = 0; i < totalDots; i++)
|
for (int i = 0; i < totalDots; i++)
|
||||||
{
|
{
|
||||||
var dot = new Ellipse
|
var dot = new Ellipse
|
||||||
@@ -122,13 +123,9 @@ namespace InstaSoftOfficeTool
|
|||||||
BtnBack.Visibility = _currentPageIndex > 0 ? Visibility.Visible : Visibility.Visible;
|
BtnBack.Visibility = _currentPageIndex > 0 ? Visibility.Visible : Visibility.Visible;
|
||||||
BtnNext.Visibility = Visibility.Visible;
|
BtnNext.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
// Last step before progress = "Telep\u00edt\u00e9s ind\u00edt\u00e1sa"
|
// On SummaryPage = "Tov\u00e1bb"
|
||||||
if (_currentPageIndex == _wizardPages.Count - 2)
|
// On PreInstallCheckPage or ProgressPage = hide
|
||||||
{
|
if (_wizardPages[_currentPageIndex] is PreInstallCheckPage ||
|
||||||
BtnNext.Content = "Telep\u00edt\u00e9s ind\u00edt\u00e1sa";
|
|
||||||
}
|
|
||||||
// On progress page, hide both
|
|
||||||
else if (_currentPageIndex == _wizardPages.Count - 1 &&
|
|
||||||
_wizardPages[_currentPageIndex] is ProgressPage)
|
_wizardPages[_currentPageIndex] is ProgressPage)
|
||||||
{
|
{
|
||||||
BtnNext.Visibility = Visibility.Collapsed;
|
BtnNext.Visibility = Visibility.Collapsed;
|
||||||
@@ -174,14 +171,20 @@ namespace InstaSoftOfficeTool
|
|||||||
}
|
}
|
||||||
|
|
||||||
ShowCurrentPage();
|
ShowCurrentPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ProceedToInstall()
|
||||||
|
{
|
||||||
|
// Jump to ProgressPage (last page in the wizard)
|
||||||
|
_currentPageIndex = _wizardPages.Count - 1;
|
||||||
|
ShowCurrentPage();
|
||||||
|
|
||||||
// Auto-start if we're on progress page
|
|
||||||
if (_wizardPages[_currentPageIndex] is ProgressPage progressPage)
|
if (_wizardPages[_currentPageIndex] is ProgressPage progressPage)
|
||||||
{
|
{
|
||||||
progressPage.StartInstallation();
|
progressPage.StartInstallation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void ShowCloseButton()
|
public void ShowCloseButton()
|
||||||
{
|
{
|
||||||
|
|||||||
67
Pages/PreInstallCheckPage.xaml
Normal file
67
Pages/PreInstallCheckPage.xaml
Normal file
@@ -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="" 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>
|
||||||
139
Pages/PreInstallCheckPage.xaml.cs
Normal file
139
Pages/PreInstallCheckPage.xaml.cs
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
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)
|
||||||
|
{
|
||||||
|
BtnRemove.IsEnabled = false;
|
||||||
|
BtnSkip.IsEnabled = false;
|
||||||
|
LogPanel.Visibility = Visibility.Visible;
|
||||||
|
|
||||||
|
bool hasC2R = false;
|
||||||
|
foreach (UIElement child in OfficeListPanel.Children)
|
||||||
|
{
|
||||||
|
if (child is CheckBox cb && cb.IsChecked == true)
|
||||||
|
{
|
||||||
|
var office = (InstalledOffice)cb.Tag;
|
||||||
|
if (office.IsClickToRun)
|
||||||
|
{
|
||||||
|
hasC2R = true;
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
await runner.RunAsync("msiexec", "/x " + office.ProductCode + " /qb");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasC2R)
|
||||||
|
{
|
||||||
|
AppendLog("Click-to-Run Office elt\u00e1vol\u00edt\u00e1sa...");
|
||||||
|
var downloader = new OdtDownloader();
|
||||||
|
downloader.StatusChanged += msg => Dispatcher.Invoke(() => AppendLog(msg));
|
||||||
|
|
||||||
|
bool ok = await downloader.DownloadAndExtractAsync();
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
string removeXml = OdtXmlGenerator.GenerateRemoveAll();
|
||||||
|
string xmlPath = Path.Combine(downloader.OdtFolder, "remove.xml");
|
||||||
|
File.WriteAllText(xmlPath, removeXml);
|
||||||
|
|
||||||
|
int exitCode = await downloader.RunRemoveAsync(xmlPath,
|
||||||
|
msg => Dispatcher.Invoke(() => AppendLog(msg)));
|
||||||
|
|
||||||
|
AppendLog(exitCode == 0
|
||||||
|
? "Office sikeresen elt\u00e1vol\u00edtva."
|
||||||
|
: "Elt\u00e1vol\u00edt\u00e1s befejez\u0151d\u00f6tt (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...");
|
||||||
|
|
||||||
|
// Auto-proceed to install after short delay
|
||||||
|
await System.Threading.Tasks.Task.Delay(1500);
|
||||||
|
_main.ProceedToInstall();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AppendLog(string text)
|
||||||
|
{
|
||||||
|
LogText.Text += DateTime.Now.ToString("HH:mm:ss") + " " + text + "\n";
|
||||||
|
LogText.ScrollToEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user