@@ -7,24 +7,59 @@ import (
77 "fmt"
88 "os/exec"
99 "strings"
10+ "time"
1011)
1112
12- // Start starts a Windows service by name.
13+ const (
14+ pollInterval = 500 * time .Millisecond
15+ stopTimeout = 60 * time .Second
16+ startTimeout = 60 * time .Second
17+ )
18+
19+ // Start starts a Windows service by name and waits until it's running.
1320func Start (serviceName string ) error {
21+ // Already running? Nothing to do
22+ if running , _ := IsActive (serviceName ); running {
23+ return nil
24+ }
25+
1426 cmd := exec .Command ("sc" , "start" , serviceName )
15- if err := cmd .Run (); err != nil {
16- return fmt .Errorf ("failed to start service %s: %w" , serviceName , err )
27+ cmd .Run () // Ignore error, we'll check actual state
28+
29+ // Poll until running or timeout
30+ deadline := time .Now ().Add (startTimeout )
31+ for time .Now ().Before (deadline ) {
32+ if running , _ := IsActive (serviceName ); running {
33+ return nil
34+ }
35+ time .Sleep (pollInterval )
1736 }
18- return nil
37+
38+ return fmt .Errorf ("timeout waiting for service %s to start" , serviceName )
1939}
2040
21- // Stop stops a Windows service by name.
41+ // Stop stops a Windows service by name and waits until it's stopped .
2242func Stop (serviceName string ) error {
43+ // Already stopped? Nothing to do
44+ status , _ := Status (serviceName )
45+ if status == StatusStopped {
46+ return nil
47+ }
48+
2349 cmd := exec .Command ("sc" , "stop" , serviceName )
24- if err := cmd .Run (); err != nil {
25- return fmt .Errorf ("failed to stop service %s: %w" , serviceName , err )
50+ cmd .Run () // Ignore error, we'll check actual state
51+
52+ // Poll until stopped or timeout
53+ deadline := time .Now ().Add (stopTimeout )
54+ for time .Now ().Before (deadline ) {
55+ status , _ := Status (serviceName )
56+ if status == StatusStopped {
57+ return nil
58+ }
59+ time .Sleep (pollInterval )
2660 }
27- return nil
61+
62+ return fmt .Errorf ("timeout waiting for service %s to stop" , serviceName )
2863}
2964
3065// Restart restarts a Windows service by stopping and starting it.
@@ -37,12 +72,11 @@ func Restart(serviceName string) error {
3772
3873// IsActive checks if a Windows service is running.
3974func IsActive (serviceName string ) (bool , error ) {
40- cmd := exec .Command ("sc" , "query" , serviceName )
41- output , err := cmd .Output ()
75+ status , err := Status (serviceName )
4276 if err != nil {
43- return false , fmt . Errorf ( "failed to query service %s: %w" , serviceName , err )
77+ return false , err
4478 }
45- return strings . Contains ( string ( output ), "RUNNING" ) , nil
79+ return status == StatusRunning , nil
4680}
4781
4882// Status returns the status of a Windows service.
0 commit comments