feat(windows): 向导内置 HiTi Windows 驱动一键安装(对齐 mac 的"装 App 即用"体验)

用户实测定论:CS-2xx 的 USB 是自定义设备(驱动包内含 CS2xxhcd.inf 内核驱动),
PavoApi 直打依赖驱动建立的 USB 通道——无驱动时枚举到设备但状态返回离线,
"免驱动"假设不成立。产品要求两平台一致:驱动随 App 内置、向导一键安装。

- assets/drivers/CS2xx_Windows_Driver.zip:HiTi 官网 CS-2xx Windows 驱动
  (2.6.25.48)整目录 zip(含 CS2xx/Setup64.exe),33MB,不入 git
- DriverInstall Windows 分支:Expand-Archive 解压到临时目录 → 递归定位
  Setup64.exe(兜底 setup/autorun)→ PowerShell Start-Process -Verb RunAs -Wait
  提权安装(UAC 一次)→ 写安装标记(HKCU\Software\zax\desktop-plugin,
  系统驱动安装状态无统一可查标志)→ finally 清理临时目录
- 向导第 2 步统一双平台状态机:驱动未装(异步查标记/目录)→"一键安装驱动
  (内置安装包)";轮询 3 秒自动刷新安装/连接状态
- bundledInstallerPath 双平台资产路径推导(mac .dmg / win .zip);
  .gitignore 增 *.zip;assets/drivers/README 更新双平台放置约定
This commit is contained in:
dzc committed 2026-09-21 16:38:11 +08:00
1 parent 527baf7ec5
commit 170e9ddc5e
4 files changed
+156 -53

No files matched your search

+27 -12
View File
@@ -48,17 +48,22 @@ class _SetupWizardState extends State<SetupWizard> {
String? _driverInstallError;
PrinterStatus? _printerStatus;
/// 驱动是否已装(null=查询中;mac=驱动目录,win=注册表安装标记)
bool? _driverInstalled;
Agent get _agent => widget.agent;
@override
void initState() {
super.initState();
_checkPrinter();
_queryDriver();
// 第 2 步期间自动轮询:用户手动装驱动 / 插上打印机后页面自动刷新
// (驱动目录判断零成本;getStatus 走 lpoptions,3s 一次可接受)
_pollTimer = Timer.periodic(const Duration(seconds: 3), (_) {
if (_step == 1 && mounted && !_driverInstalling) {
_checkPrinter(silent: true);
_queryDriver();
}
});
}
@@ -71,6 +76,11 @@ class _SetupWizardState extends State<SetupWizard> {
super.dispose();
}
Future<void> _queryDriver() async {
final installed = await DriverInstall.queryInstalled();
if (mounted) setState(() => _driverInstalled = installed);
}
Future<void> _checkPrinter({bool silent = false}) async {
if (!silent) setState(() => _printerChecking = true);
try {
@@ -192,16 +202,17 @@ class _SetupWizardState extends State<SetupWizard> {
// ---------------- Step 1:打印机检测 ----------------
/// 一键安装内置驱动(mac):装完自动重检(队列要等打印机连上/系统识别后才出现)。
/// 一键安装内置驱动:装完自动重检(队列要等打印机连上/系统识别后才出现)。
Future<void> _installDriver() async {
final dmg = DriverInstall.bundledDmgPath();
if (dmg == null) return;
final installer = DriverInstall.bundledInstallerPath();
if (installer == null) return;
setState(() {
_driverInstalling = true;
_driverInstallError = null;
});
try {
await DriverInstall.installFromDmg(dmg, onLog: _agent.log.write);
await DriverInstall.install(installer, onLog: _agent.log.write);
await _queryDriver();
await _checkPrinter();
} catch (e) {
if (mounted) setState(() => _driverInstallError = '$e');
@@ -213,8 +224,8 @@ class _SetupWizardState extends State<SetupWizard> {
Widget _stepPrinter(ColorScheme scheme) {
final s = _printerStatus;
final ready = s != null && s.online;
final driverMissing = Platform.isMacOS && !DriverInstall.isInstalled();
final bundledDmg = Platform.isMacOS ? DriverInstall.bundledDmgPath() : null;
final driverMissing = _driverInstalled == false;
final bundledInstaller = DriverInstall.bundledInstallerPath();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@@ -227,17 +238,19 @@ class _SetupWizardState extends State<SetupWizard> {
),
const SizedBox(height: 12),
// mac:驱动未装 → 首选一键安装内置驱动,其次官网链接
// 驱动未装 → 首选一键安装内置驱动,其次官网链接(mac/win 通用)
if (driverMissing) ...[
Text(
'本机尚未安装 HiTi 打印机驱动(mac 打印必需的系统组件)。',
Platform.isMacOS
? '本机尚未安装 HiTi 打印机驱动(mac 打印必需的系统组件)。'
: '本机尚未安装 HiTi 打印机驱动。直打通道需要驱动建立的 USB 连接,装好即可自动识别打印机。',
style: Theme.of(context).textTheme.bodySmall?.copyWith(height: 1.6),
),
const SizedBox(height: 8),
Row(
children: [
FilledButton.tonalIcon(
onPressed: _driverInstalling || bundledDmg == null ? null : _installDriver,
onPressed: _driverInstalling || bundledInstaller == null ? null : _installDriver,
icon: _driverInstalling
? const SizedBox(
width: 14,
@@ -246,7 +259,7 @@ class _SetupWizardState extends State<SetupWizard> {
)
: const Icon(Icons.download, size: 16),
label: Text(_driverInstalling
? '正在安装…(弹窗中输入管理员密码)'
? '正在安装…(请在系统弹窗中确认)'
: '一键安装驱动(内置安装包)'),
),
const SizedBox(width: 8),
@@ -257,7 +270,7 @@ class _SetupWizardState extends State<SetupWizard> {
),
],
),
if (bundledDmg == null)
if (bundledInstaller == null)
Padding(
padding: const EdgeInsets.only(top: 4),
child: Text(
@@ -278,7 +291,9 @@ class _SetupWizardState extends State<SetupWizard> {
),
const SizedBox(height: 8),
Text(
'安装完成后页面会自动刷新(也可手动重新检测);随后 USB 连接打印机并开机,系统识别出现打印队列即完成。',
Platform.isMacOS
? '安装完成后:USB 连接打印机并开机,系统识别出现打印队列即完成。'
: '安装完成后 USB 连接打印机并开机,回到这里重新检测即完成。',
style: Theme.of(context).textTheme.bodySmall,
),
const SizedBox(height: 4),