Files
Better-Seewo/Installer/Pages/InstallPage.xaml.cs
miao-moe bb0c8832a0 feat: 新增一键构建脚本 (v2.0.1)
- 添加 build.ps1 PowerShell 构建脚本
- 添加 build.bat 批处理入口(双击一键构建)
- 支持 Debug/Release 配置切换
- 支持自包含模式发布
- 自动检测 .NET SDK、清理输出、编译打包
2026-06-28 07:14:37 +00:00

347 lines
12 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 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
}
}