@@ -2,8 +2,6 @@ package launch
22
33import (
44 "context"
5- "encoding/csv"
6- "os/exec"
75 "path/filepath"
86 "strings"
97 "syscall"
@@ -14,6 +12,7 @@ import (
1412
1513 "github.com/liteldev/LeviLauncher/internal/discord"
1614 "github.com/liteldev/LeviLauncher/internal/registry"
15+ "golang.org/x/sys/windows"
1716)
1817
1918const (
@@ -52,39 +51,51 @@ func EnsureGamingServicesInstalled(ctx context.Context) bool {
5251 return true
5352}
5453
54+ func normalizeProcessPath (p string ) string {
55+ s := strings .ToLower (filepath .Clean (strings .TrimSpace (p )))
56+ s = strings .TrimPrefix (s , `\\?\` )
57+ s = strings .TrimPrefix (s , `\??\` )
58+ return s
59+ }
60+
5561func isGameRunning (versionDir string ) bool {
5662 if versionDir == "" {
5763 return false
5864 }
59- cmd := exec .Command ("powershell" , "-NoProfile" , "-Command" , "Get-CimInstance Win32_Process -Filter \" Name='Minecraft.Windows.exe'\" | Select-Object ExecutablePath | ConvertTo-Csv -NoTypeInformation" )
60- cmd .SysProcAttr = & syscall.SysProcAttr {HideWindow : true }
61- out , err := cmd .Output ()
65+
66+ snapshot , err := windows .CreateToolhelp32Snapshot (windows .TH32CS_SNAPPROCESS , 0 )
6267 if err != nil {
6368 return false
6469 }
65- reader := csv .NewReader (strings .NewReader (string (out )))
66- records , err := reader .ReadAll ()
67- if err != nil || len (records ) < 2 {
68- return false
69- }
70- idx := - 1
71- for i , col := range records [0 ] {
72- if strings .EqualFold (col , "ExecutablePath" ) {
73- idx = i
74- break
75- }
76- }
77- if idx == - 1 {
70+ defer windows .CloseHandle (snapshot )
71+
72+ cleanVerDir := normalizeProcessPath (versionDir )
73+
74+ var entry windows.ProcessEntry32
75+ entry .Size = uint32 (unsafe .Sizeof (entry ))
76+ if err := windows .Process32First (snapshot , & entry ); err != nil {
7877 return false
7978 }
80- cleanVerDir := strings .ToLower (filepath .Clean (versionDir ))
81- for _ , row := range records [1 :] {
82- if len (row ) <= idx {
83- continue
79+
80+ for {
81+ if strings .EqualFold (windows .UTF16ToString (entry .ExeFile [:]), "Minecraft.Windows.exe" ) {
82+ h , err := windows .OpenProcess (windows .PROCESS_QUERY_LIMITED_INFORMATION , false , entry .ProcessID )
83+ if err == nil {
84+ buf := make ([]uint16 , 1024 )
85+ size := uint32 (len (buf ))
86+ if err := windows .QueryFullProcessImageName (h , 0 , & buf [0 ], & size ); err == nil && size > 0 {
87+ p := normalizeProcessPath (windows .UTF16ToString (buf [:size ]))
88+ _ = windows .CloseHandle (h )
89+ if strings .HasPrefix (p , cleanVerDir ) {
90+ return true
91+ }
92+ } else {
93+ _ = windows .CloseHandle (h )
94+ }
95+ }
8496 }
85- path := strings .ToLower (filepath .Clean (row [idx ]))
86- if strings .HasPrefix (path , cleanVerDir ) {
87- return true
97+ if err := windows .Process32Next (snapshot , & entry ); err != nil {
98+ break
8899 }
89100 }
90101 return false
@@ -192,7 +203,7 @@ func MonitorGameProcess(ctx context.Context, versionDir string) {
192203 // 似乎会出现Bug,后续修复
193204 //w := application.Get().Window.Current()
194205 //if w != nil {
195- //w.Restore()
206+ //w.Restore()
196207 //}
197208 return
198209 }
0 commit comments