Files
Better-Seewo/Installer/Pages/InstallPage.xaml.cs

347 lines
12 KiB
C#
Raw Normal View History

/*
* InstallPage.xaml.cs - Better-Seewo
*
*
*/
using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
namespace Better_Seewo.Installer.Pages
{
/// <summary>
/// InstallPage 的交互逻辑 - 安装向导安装页面
/// </summary>
public partial class InstallPage : Page
{
/// <summary>
/// 当前安装进度0-100
/// </summary>
private int _currentProgress;
/// <summary>
/// 标记安装是否已启动
/// </summary>
private bool _isStarted;
/// <summary>
/// 构造函数,初始化页面组件
/// </summary>
public InstallPage()
{
InitializeComponent();
// 设置默认安装路径
TxtInstallPath.Text = App.InstallPath;
}
/// <summary>
/// 浏览按钮点击 - 选择安装路径
/// </summary>
private void BtnBrowse_Click(object sender, RoutedEventArgs e)
{
// 如果安装已开始则不允许更改路径
if (_isStarted) return;
// 使用文件夹浏览对话框选择安装路径
var dialog = new System.Windows.Forms.FolderBrowserDialog
{
Description = "选择 Better-Seewo 安装路径",
ShowNewFolderButton = true,
SelectedPath = TxtInstallPath.Text
};
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
TxtInstallPath.Text = dialog.SelectedPath;
App.InstallPath = dialog.SelectedPath;
}
}
/// <summary>
/// 开始安装过程(由主窗口调用)
/// 模拟三个安装步骤检测EN5 -> 复制文件 -> 注册插件
/// </summary>
public async void StartInstallation()
{
if (_isStarted) return;
_isStarted = true;
try
{
// 禁用路径输入和浏览按钮
TxtInstallPath.IsReadOnly = true;
// 更新安装路径
App.InstallPath = TxtInstallPath.Text;
// ===== 步骤 1检测 EN5 安装状态 =====
SetStepStatus(1, "running");
AppendLog($"[{DateTime.Now:HH:mm:ss}] 正在检测 EasiNote5 安装状态...");
await Task.Delay(800);
// 检查 EN5 安装目录是否存在
string en5Path = GetEn5InstallPath();
bool en5Exists = !string.IsNullOrEmpty(en5Path) && Directory.Exists(en5Path);
if (en5Exists)
{
AppendLog($"[{DateTime.Now:HH:mm:ss}] 已检测到 EasiNote5 安装路径: {en5Path}");
SetStepStatus(1, "success");
}
else
{
AppendLog($"[{DateTime.Now:HH:mm:ss}] 未检测到 EasiNote5 安装,将继续安装到指定路径");
SetStepStatus(1, "warning");
}
UpdateProgress(25);
await Task.Delay(300);
// ===== 步骤 2复制插件文件 =====
SetStepStatus(2, "running");
AppendLog($"[{DateTime.Now:HH:mm:ss}] 正在复制插件文件...");
await Task.Delay(600);
// 创建目标目录
string installDir = App.InstallPath;
try
{
if (!Directory.Exists(installDir))
{
Directory.CreateDirectory(installDir);
AppendLog($"[{DateTime.Now:HH:mm:ss}] 已创建安装目录: {installDir}");
}
// TODO: 实际安装时,将插件文件从安装包复制到目标目录
// 以下为模拟文件复制过程
string[] mockFiles = {
"Better-EN5.dll",
"Better-EN5.pdb",
"Newtonsoft.Json.dll",
"config.json"
};
foreach (var file in mockFiles)
{
await Task.Delay(200);
AppendLog($"[{DateTime.Now:HH:mm:ss}] 正在复制: {file}");
UpdateProgress(25 + (Array.IndexOf(mockFiles, file) + 1) * 10);
}
AppendLog($"[{DateTime.Now:HH:mm:ss}] 插件文件复制完成");
SetStepStatus(2, "success");
}
catch (Exception ex)
{
AppendLog($"[{DateTime.Now:HH:mm:ss}] 复制文件失败: {ex.Message}");
SetStepStatus(2, "error");
throw;
}
await Task.Delay(300);
// ===== 步骤 3注册插件 =====
SetStepStatus(3, "running");
AppendLog($"[{DateTime.Now:HH:mm:ss}] 正在注册插件...");
await Task.Delay(500);
try
{
// TODO: 实际安装时,写入注册表或配置文件完成插件注册
await Task.Delay(400);
AppendLog($"[{DateTime.Now:HH:mm:ss}] 正在写入插件配置...");
UpdateProgress(80);
await Task.Delay(300);
AppendLog($"[{DateTime.Now:HH:mm:ss}] 正在注册 EasiNote5 插件组件...");
UpdateProgress(90);
await Task.Delay(300);
AppendLog($"[{DateTime.Now:HH:mm:ss}] 插件注册完成");
SetStepStatus(3, "success");
}
catch (Exception ex)
{
AppendLog($"[{DateTime.Now:HH:mm:ss}] 注册插件失败: {ex.Message}");
SetStepStatus(3, "error");
throw;
}
// ===== 安装完成 =====
UpdateProgress(100);
AppendLog($"[{DateTime.Now:HH:mm:ss}] ========================================");
AppendLog($"[{DateTime.Now:HH:mm:ss}] 安装完成Better-Seewo v{App.AppVersion} 已成功安装");
AppendLog($"[{DateTime.Now:HH:mm:ss}] 安装路径: {App.InstallPath}");
// 延迟后自动切换到完成页
await Task.Delay(1000);
// 通知主窗口安装完成
if (Window.GetWindow(this) is MainWindow mainWindow)
{
mainWindow.OnInstallCompleted();
}
}
catch (Exception ex)
{
AppendLog($"[{DateTime.Now:HH:mm:ss}] 安装过程中发生错误: {ex.Message}");
MessageBox.Show(
$"安装失败:{ex.Message}",
"Better-Seewo 安装程序",
MessageBoxButton.OK,
MessageBoxImage.Error
);
// 恢复按钮状态,允许重试
if (Window.GetWindow(this) is MainWindow mainWindow)
{
mainWindow.BtnInstall.IsEnabled = true;
mainWindow.BtnInstall.Content = "重试安装 \uE74E;";
mainWindow.BtnBack.IsEnabled = true;
}
App.IsInstalling = false;
_isStarted = false;
}
}
#region ===== =====
/// <summary>
/// 获取 EasiNote5 的安装路径
/// 检查常见的 EN5 安装目录
/// </summary>
private static string GetEn5InstallPath()
{
// 常见的 EasiNote5 安装路径
string[] possiblePaths = {
@"C:\Program Files (x86)\Seewo\EasiNote5",
@"C:\Program Files\Seewo\EasiNote5",
@"D:\Program Files (x86)\Seewo\EasiNote5",
@"D:\Program Files\Seewo\EasiNote5"
};
foreach (var path in possiblePaths)
{
if (Directory.Exists(path))
{
return path;
}
}
return null;
}
/// <summary>
/// 设置安装步骤的状态图标
/// </summary>
/// <param name="step">步骤编号1-3</param>
/// <param name="status">状态running/success/warning/error</param>
private void SetStepStatus(int step, string status)
{
// 确保在 UI 线程执行
Dispatcher.Invoke(() =>
{
var icon = step switch
{
1 => Step1Icon,
2 => Step2Icon,
3 => Step3Icon,
_ => Step1Icon
};
if (icon == null) return;
// 根据状态设置图标和颜色
icon.Text = status switch
{
"running" => "⏳",
"success" => "✓",
"warning" => "⚠",
"error" => "✗",
_ => "⏳"
};
icon.Foreground = status switch
{
"running" => (System.Windows.Media.Brush)FindResource("WarningBrush"),
"success" => (System.Windows.Media.Brush)FindResource("SuccessBrush"),
"warning" => (System.Windows.Media.Brush)FindResource("WarningBrush"),
"error" => (System.Windows.Media.Brush)FindResource("ErrorBrush"),
_ => (System.Windows.Media.Brush)FindResource("TextSecondaryBrush")
};
});
}
/// <summary>
/// 更新进度条和百分比文字
/// </summary>
/// <param name="progress">进度值0-100</param>
private void UpdateProgress(int progress)
{
_currentProgress = Math.Clamp(progress, 0, 100);
// 确保在 UI 线程执行
Dispatcher.Invoke(() =>
{
// 更新百分比文字
TxtProgress.Text = $"{_currentProgress}%";
// 更新进度条宽度(使用动画)
var parentWidth = ((FrameworkElement)ProgressFill.Parent).ActualWidth;
var widthAnimation = new DoubleAnimation
{
From = (ProgressFill.ActualWidth > 0 ? ProgressFill.ActualWidth : 0),
To = (_currentProgress / 100.0) * parentWidth,
Duration = TimeSpan.FromMilliseconds(300),
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
};
// 如果父容器尚未布局完成,直接设置宽度
if (parentWidth == 0)
{
// 等待布局完成后设置
ProgressFill.Loaded += (s, e) =>
{
var loadedAnimation = new DoubleAnimation
{
From = 0,
To = (_currentProgress / 100.0) * ((FrameworkElement)ProgressFill.Parent).ActualWidth,
Duration = TimeSpan.FromMilliseconds(300),
EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut }
};
ProgressFill.BeginAnimation(WidthProperty, loadedAnimation);
};
}
else
{
ProgressFill.BeginAnimation(WidthProperty, widthAnimation);
}
});
}
/// <summary>
/// 向日志文本框追加一行日志
/// </summary>
/// <param name="message">日志消息</param>
private void AppendLog(string message)
{
// 确保在 UI 线程执行
Dispatcher.Invoke(() =>
{
TxtLog.Text += message + Environment.NewLine;
// 自动滚动到底部
LogScrollViewer.ScrollToEnd();
});
}
#endregion
}
}