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:
1 parent
527baf7ec5
commit
170e9ddc5e
4 files changed
+156
-53
No files matched your search
+27
-12
@@ -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),
|
||||
|
||||
Reference in new issue
Block a user