windows/svc: stop service before deletion in TestExample

TestExample normally stops and deletes test service at the end of the
test. But, if TestExample does not complete for some reason, test
service might remain running and installed.

There is some code that deletes "left over" test service before starting
the test. But that code fails, if service is running. Deletion only
works, if service is not running. This CL adds code to stop the "left
over" service so it can be deleted.

Update golang/go#42211

Change-Id: I826dd587063265c5b96076668c3704c0a7eaa3d8
Reviewed-on: https://go-review.googlesource.com/c/sys/+/267603
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Alex Brainman <alex.brainman@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/windows/svc/svc_test.go b/windows/svc/svc_test.go
index 7e87053..5bf123d 100644
--- a/windows/svc/svc_test.go
+++ b/windows/svc/svc_test.go
@@ -49,6 +49,32 @@
 	}
 }
 
+// stopAndDeleteIfInstalled stops and deletes service name,
+// if the service is running and / or installed.
+func stopAndDeleteIfInstalled(t *testing.T, m *mgr.Mgr, name string) {
+	s, err := m.OpenService(name)
+	if err != nil {
+		// Service is not installed.
+		return
+
+	}
+	defer s.Close()
+
+	// Make sure the service is not running, otherwise we won't be able to delete it.
+	if getState(t, s) == svc.Running {
+		_, err = s.Control(svc.Stop)
+		if err != nil {
+			t.Fatalf("Control(%s) failed: %s", s.Name, err)
+		}
+		waitState(t, s, svc.Stopped)
+	}
+
+	err = s.Delete()
+	if err != nil {
+		t.Fatalf("Delete failed: %s", err)
+	}
+}
+
 func TestExample(t *testing.T) {
 	if testing.Short() {
 		t.Skip("skipping test in short mode - it modifies system services")
@@ -74,16 +100,9 @@
 		t.Fatalf("failed to build service program: %v\n%v", err, string(o))
 	}
 
-	s, err := m.OpenService(name)
-	if err == nil {
-		err = s.Delete()
-		if err != nil {
-			s.Close()
-			t.Fatalf("Delete failed: %s", err)
-		}
-		s.Close()
-	}
-	s, err = m.CreateService(name, exepath, mgr.Config{DisplayName: "my service"}, "is", "auto-started")
+	stopAndDeleteIfInstalled(t, m, name)
+
+	s, err := m.CreateService(name, exepath, mgr.Config{DisplayName: "my service"}, "is", "auto-started")
 	if err != nil {
 		t.Fatalf("CreateService(%s) failed: %v", name, err)
 	}