diff --git a/internal/service/service_windows.go b/internal/service/service_windows.go index 012132f..5827fab 100644 --- a/internal/service/service_windows.go +++ b/internal/service/service_windows.go @@ -146,6 +146,7 @@ func Install(configPath string, copyBin bool, version string) error { if st, qErr := s.Query(); qErr == nil && (st.State == svc.Running || st.State == svc.StartPending) { wasRunning = true + fmt.Println("stopping the running gpu-turnstile service") if err := stopAndWait(s); err != nil { return err } @@ -161,6 +162,7 @@ func Install(configPath string, copyBin bool, version string) error { } installedExe := filepath.Join(installDir, "gpu-turnstile.exe") if same, _ := sameFileContent(exe, installedExe); !same { + fmt.Printf("installing %s\n", installedExe) if err := copyFile(exe, installedExe); err != nil { return fmt.Errorf("copy binary to %s: %w", installedExe, err) } @@ -208,6 +210,7 @@ func Install(configPath string, copyBin bool, version string) error { // Best effort: start now instead of waiting for the next boot. A // missing config (no consumer URLs) fails the start; the service stays // registered and can be started once the config exists. + fmt.Println("starting the gpu-turnstile service") s.Start() return nil } @@ -243,6 +246,7 @@ func Install(configPath string, copyBin bool, version string) error { return err } if wasRunning { + fmt.Println("starting the gpu-turnstile service") if err := s.Start(); err != nil { return fmt.Errorf("start service: %w", err) } @@ -477,21 +481,32 @@ func RelaunchElevated(args []string) (int, error) { // grantAccess gives the virtual account the icacls permission set (e.g. // "(OI)(CI)(M)") on path. func grantAccess(path, perms string) error { - out, err := exec.Command("icacls", path, "/grant", virtualAccount+":"+perms).CombinedOutput() - if err != nil { - return fmt.Errorf("grant %s access to %s: %w (%s)", virtualAccount, path, err, strings.TrimSpace(string(out))) - } - return nil + return runIcacls(path, perms, false) } // grantAccessTree is grantAccess with /T: the ACE is applied to the // existing tree, not just inherited by children created later. Needed when -// the tree already exists, e.g. a ComfyUI install in a user profile. +// the tree already exists, e.g. a ComfyUI install in a user profile. On a +// large tree (a venv has tens of thousands of files) this takes minutes, +// so it says what it is doing instead of looking hung. func grantAccessTree(path, perms string) error { - out, err := exec.Command("icacls", path, "/grant", virtualAccount+":"+perms, "/T").CombinedOutput() + return runIcacls(path, perms, true) +} + +func runIcacls(path, perms string, recursive bool) error { + args := []string{path, "/grant", virtualAccount + ":" + perms} + if recursive { + fmt.Printf("granting %s modify access to %s (large trees can take minutes)\n", virtualAccount, path) + args = append(args, "/T") + } + start := time.Now() + out, err := exec.Command("icacls", args...).CombinedOutput() if err != nil { return fmt.Errorf("grant %s access to %s: %w (%s)", virtualAccount, path, err, strings.TrimSpace(string(out))) } + if recursive { + fmt.Printf("access granted in %s\n", time.Since(start).Round(time.Second)) + } return nil }