@@ -4,8 +4,149 @@ package main
44
55import (
66 "fmt"
7+ "log"
8+ "os"
9+ "sort"
10+ "strconv"
11+ "strings"
12+ "time"
13+
14+ "github.com/OpenSysKit/backend/internal/driver"
715)
816
917func runAutoUninstallMode () error {
10- return fmt .Errorf ("autouninstall 已禁用:请使用显式 uninstall 命令执行完整卸载,避免主进程退出阶段蓝屏" )
18+ delay := parseAutoUninstallDelay ()
19+ handles , err := parseAutoUninstallHandles ()
20+ if err != nil {
21+ return err
22+ }
23+ if len (handles ) == 0 {
24+ return fmt .Errorf ("autouninstall 未提供可卸载的 handle" )
25+ }
26+
27+ log .Printf ("autouninstall 子进程启动: delay=%s handles=%s" , delay , formatHandleList (handles ))
28+ if delay > 0 {
29+ time .Sleep (delay )
30+ }
31+
32+ log .Printf ("autouninstall 开始执行完整卸载" )
33+ if err := runAutoUninstall (handles ); err != nil {
34+ return fmt .Errorf ("autouninstall 卸载失败: %w" , err )
35+ }
36+ log .Printf ("autouninstall 卸载完成" )
37+ return nil
38+ }
39+
40+ func runAutoUninstall (handles []uint64 ) error {
41+ loader , err := driver .OpenExistingLoader ()
42+ if err != nil {
43+ return fmt .Errorf ("autouninstall 无法连接 WinDrive(\\ \\ .\\ DriverLoader): %w" , err )
44+ }
45+ defer loader .Close ()
46+
47+ drivers , err := loader .ListMappedDrivers ()
48+ if err != nil {
49+ return err
50+ }
51+ if len (drivers ) == 0 {
52+ log .Printf ("autouninstall 未检测到映射驱动,跳过 OpenSysKit 卸载" )
53+ } else {
54+ existing := make (map [uint64 ]struct {}, len (drivers ))
55+ for _ , row := range drivers {
56+ existing [row .Handle ] = struct {}{}
57+ }
58+
59+ filtered := make ([]uint64 , 0 , len (handles ))
60+ for _ , h := range dedupHandles (handles ) {
61+ if _ , ok := existing [h ]; ok {
62+ filtered = append (filtered , h )
63+ } else {
64+ log .Printf ("autouninstall 跳过不存在的 handle=%d (当前映射: %s)" , h , formatHandles (drivers ))
65+ }
66+ }
67+ if len (filtered ) == 0 {
68+ return fmt .Errorf ("autouninstall 指定 handle 均不存在,当前映射: %s" , formatHandles (drivers ))
69+ }
70+
71+ sort .Slice (filtered , func (i , j int ) bool { return filtered [i ] > filtered [j ] })
72+ if waitForDeviceRelease (`\\.\OpenSysKit` , 15 * time .Second ) {
73+ log .Println ("autouninstall 检测到设备引用已释放,开始卸载" )
74+ } else {
75+ log .Println ("autouninstall 警告: 设备可能仍被占用,仍尝试卸载" )
76+ }
77+
78+ log .Printf ("autouninstall 计划卸载 handle: %s" , formatHandleList (filtered ))
79+ for _ , handle := range filtered {
80+ if err = unloadHandleWithRetry (loader , handle , 5 ); err != nil {
81+ return err
82+ }
83+ }
84+ }
85+
86+ after , err := loader .ListMappedDrivers ()
87+ if err != nil {
88+ return err
89+ }
90+ if len (after ) != 0 {
91+ return fmt .Errorf ("autouninstall 卸载后仍存在映射驱动: %s" , formatHandles (after ))
92+ }
93+
94+ log .Println ("autouninstall 下发 WinDrive allow-unload" )
95+ if err = loader .AllowUnload (); err != nil {
96+ return err
97+ }
98+
99+ loader .Close ()
100+ log .Println ("autouninstall 卸载 DriverLoader 服务" )
101+ if err = driver .UninstallLoaderService (); err != nil {
102+ return err
103+ }
104+ return nil
105+ }
106+
107+ func parseAutoUninstallDelay () time.Duration {
108+ for _ , arg := range os .Args [2 :] {
109+ if strings .HasPrefix (arg , "--delay=" ) {
110+ raw := strings .TrimSpace (strings .TrimPrefix (arg , "--delay=" ))
111+ if raw == "" {
112+ continue
113+ }
114+ seconds , err := strconv .Atoi (raw )
115+ if err != nil || seconds < 0 {
116+ log .Printf ("警告: 非法 autouninstall delay 参数 %q,改用 1 秒" , raw )
117+ return time .Second
118+ }
119+ if seconds == 0 {
120+ return 0
121+ }
122+ return time .Duration (seconds ) * time .Second
123+ }
124+ }
125+ return time .Second
126+ }
127+
128+ func parseAutoUninstallHandles () ([]uint64 , error ) {
129+ for _ , arg := range os .Args [2 :] {
130+ if strings .HasPrefix (arg , "--handles=" ) {
131+ raw := strings .TrimSpace (strings .TrimPrefix (arg , "--handles=" ))
132+ if raw == "" {
133+ return nil , nil
134+ }
135+ parts := strings .Split (raw , "," )
136+ handles := make ([]uint64 , 0 , len (parts ))
137+ for _ , part := range parts {
138+ part = strings .TrimSpace (part )
139+ if part == "" {
140+ continue
141+ }
142+ h , err := strconv .ParseUint (part , 10 , 64 )
143+ if err != nil {
144+ return nil , fmt .Errorf ("解析 autouninstall handle 失败 %q: %w" , part , err )
145+ }
146+ handles = append (handles , h )
147+ }
148+ return handles , nil
149+ }
150+ }
151+ return nil , nil
11152}
0 commit comments