func installService(name, desc string, args ...string) error { exepath, err := exePath() if err != nil { return err } if len(args) > 0 { exepath = exepath + " " + strings.Join(args, " ") } println("exepath:", exepath) m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(name) if err == nil { s.Close() return fmt.Errorf("service %s already exists", name) } s, err = m.CreateService(name, exepath, mgr.Config{ DisplayName: desc, StartType: windows.SERVICE_AUTO_START, }) if err != nil { return err } defer s.Close() err = eventlog.InstallAsEventCreate(name, eventlog.Error|eventlog.Warning|eventlog.Info) if err != nil { s.Delete() return fmt.Errorf("SetupEventLogSource() failed: %s", err) } return nil }
func removeService(name string) error { log.Info("Removing service") m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(name) if err != nil { log.Info("Service not installed") return ServiceNotFound } defer s.Close() err = s.Delete() if err != nil { return err } err = eventlog.Remove(name) if err != nil { return fmt.Errorf("RemoveEventLogSource() failed: %s", err) } log.Info("Service removed") return nil }
func installService(name, desc string) error { exepath, err := exePath() if err != nil { return err } m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(name) if err == nil { s.Close() return fmt.Errorf("service %s already exists", name) } s, err = m.CreateService(name, exepath, mgr.Config{DisplayName: desc, StartType: 2}, "is", "auto-started") if err != nil { return err } defer s.Close() err = eventlog.InstallAsEventCreate(name, eventlog.Error|eventlog.Warning|eventlog.Info) if err != nil { s.Delete() return fmt.Errorf("SetupEventLogSource() failed: %s", err) } return nil }
func createService(c *cli.Context) { exePath, err := filepath.Abs("gcp-windows-connector.exe") if err != nil { fmt.Printf("Failed to find the connector executable: %s\n", err) os.Exit(1) } m, err := mgr.Connect() if err != nil { fmt.Printf("Failed to connect to service control manager: %s\n", err) os.Exit(1) } defer m.Disconnect() config := mgr.Config{ DisplayName: lib.ConnectorName, Description: "Shares printers with Google Cloud Print", Dependencies: []string{"Spooler"}, StartType: mgr.StartAutomatic, } service, err := m.CreateService(lib.ConnectorName, exePath, config) if err != nil { fmt.Printf("Failed to create service: %s\n", err) os.Exit(1) } defer service.Close() fmt.Println("Service created successfully") }
func controlService(name string, c svc.Cmd, to svc.State) error { m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(name) if err != nil { return fmt.Errorf("could not access service: %v", err) } defer s.Close() status, err := s.Control(c) if err != nil { return fmt.Errorf("could not send control=%d: %v", c, err) } timeout := time.Now().Add(10 * time.Second) for status.State != to { if timeout.Before(time.Now()) { return fmt.Errorf("timeout waiting for service to go to state=%d", to) } time.Sleep(300 * time.Millisecond) status, err = s.Query() if err != nil { return fmt.Errorf("could not retrieve service status: %v", err) } } return nil }
func (ws *windowsService) Install() error { exepath, err := ws.execPath() if err != nil { return err } m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(ws.Name) if err == nil { s.Close() return fmt.Errorf("service %s already exists", ws.Name) } s, err = m.CreateService(ws.Name, exepath, mgr.Config{ DisplayName: ws.DisplayName, Description: ws.Description, StartType: mgr.StartAutomatic, ServiceStartName: ws.UserName, Password: ws.Option.string("Password", ""), Dependencies: ws.Dependencies, }, ws.Arguments...) if err != nil { return err } defer s.Close() err = eventlog.InstallAsEventCreate(ws.Name, eventlog.Error|eventlog.Warning|eventlog.Info) if err != nil { s.Delete() return fmt.Errorf("InstallAsEventCreate() failed: %s", err) } return nil }
func uninstallService(name string) { log.Infof("Uninstalling service %s", name) m, err := mgr.Connect() if err != nil { log.Errorf("Failed to connect to service manager: %v", err) } defer m.Disconnect() s, err := m.OpenService(name) // service exist so we try to uninstall it if err != nil { log.Debugf("Service %s doesn't exist, no uninstall action needed", name) return } defer s.Close() err = s.Delete() if err != nil { log.Errorf("Can't delete service %s: %v", name, err) } err = eventlog.Remove(s.Name) if err != nil { log.Errorf("RemoveEventLogSource() failed: %s", err) } return }
func InstallService(appPath, name, desc string, params ...string) error { m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(name) if err == nil { s.Close() return fmt.Errorf("winsvc.InstallService: service %s already exists", name) } s, err = m.CreateService(name, appPath, mgr.Config{ DisplayName: desc, StartType: windows.SERVICE_AUTO_START, }, params..., ) if err != nil { return err } defer s.Close() err = eventlog.InstallAsEventCreate(name, eventlog.Error|eventlog.Warning|eventlog.Info) if err != nil { s.Delete() return fmt.Errorf("winsvc.InstallService: InstallAsEventCreate failed, err = %v", err) } return nil }
func QueryService(name string) (status string, err error) { m, err := mgr.Connect() if err != nil { return } defer m.Disconnect() s, err := m.OpenService(name) if err != nil { err = fmt.Errorf("winsvc.QueryService: could not access service: %v", err) return } defer s.Close() statusCode, err := s.Query() if err != nil { return } switch statusCode.State { case svc.Stopped: return "Stopped", nil case svc.StartPending: return "StartPending", nil case svc.StopPending: return "StopPending", nil case svc.Running: return "Running", nil case svc.ContinuePending: return "ContinuePending", nil case svc.PausePending: return "PausePending", nil case svc.Paused: return "Paused", nil } panic("unreached") }
func (ws *windowsService) Install() error { exepath, err := osext.Executable() if err != nil { return err } // Used if path contains a space. exepath = `"` + exepath + `"` m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(ws.name) if err == nil { s.Close() return fmt.Errorf("service %s already exists", ws.name) } s, err = m.CreateService(ws.name, exepath, mgr.Config{ DisplayName: ws.displayName, Description: ws.description, StartType: mgr.StartAutomatic, }) if err != nil { return err } defer s.Close() err = eventlog.InstallAsEventCreate(ws.name, eventlog.Error|eventlog.Warning|eventlog.Info) if err != nil { s.Delete() return fmt.Errorf("InstallAsEventCreate() failed: %s", err) } return nil }
func TestMyService(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode - it modifies system services") } const name = "myservice" m, err := mgr.Connect() if err != nil { if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERROR_ACCESS_DENIED { t.Skip("Skipping test: we don't have rights to manage services.") } t.Fatalf("SCM connection failed: %s", err) } defer m.Disconnect() c := mgr.Config{ StartType: mgr.StartDisabled, DisplayName: "my service", Description: "my service is just a test", Dependencies: []string{"LanmanServer", "W32Time"}, } exename := os.Args[0] exepath, err := filepath.Abs(exename) if err != nil { t.Fatalf("filepath.Abs(%s) failed: %s", exename, err) } install(t, m, name, exepath, c) s, err := m.OpenService(name) if err != nil { t.Fatalf("service %s is not installed", name) } defer s.Close() c.BinaryPathName = exepath c = testConfig(t, s, c) c.StartType = mgr.StartManual err = s.UpdateConfig(c) if err != nil { t.Fatalf("UpdateConfig failed: %v", err) } testConfig(t, s, c) remove(t, s) }
func (r *SvcRunner) ValidateBeforeStart() error { execPath, err := exec.LookPath(r.exec) if err != nil { return backends.SetStatusLogErrorf(r.name, "Failed to find collector executable %s", r.exec) } m, err := mgr.Connect() if err != nil { return backends.SetStatusLogErrorf(r.name, "Failed to connect to service manager: %v", err) } defer m.Disconnect() serviceConfig := mgr.Config{ DisplayName: "Graylog collector sidecar - " + r.name + " backend", Description: "Wrapper service for the NXLog backend", BinaryPathName: "\"" + r.exec + "\" " + strings.Join(r.args, " ")} s, err := m.OpenService(r.serviceName) // service exist so we only update the properties if err == nil { defer s.Close() log.Debugf("[%s] service %s already exists, updating properties", r.name) currentConfig, err := s.Config() if err == nil { currentConfig.DisplayName = serviceConfig.DisplayName currentConfig.Description = serviceConfig.Description currentConfig.BinaryPathName = serviceConfig.BinaryPathName } err = s.UpdateConfig(currentConfig) if err != nil { backends.SetStatusLogErrorf(r.name, "Failed to update service: %v", err) } // service needs to be created } else { s, err = m.CreateService(r.serviceName, execPath, serviceConfig) if err != nil { backends.SetStatusLogErrorf(r.name, "Failed to install service: %v", err) } defer s.Close() err = eventlog.InstallAsEventCreate(r.serviceName, eventlog.Error|eventlog.Warning|eventlog.Info) if err != nil { s.Delete() backends.SetStatusLogErrorf(r.name, "SetupEventLogSource() failed: %v", err) } } return nil }
func (ws *windowsService) Start() error { m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(ws.Name) if err != nil { return err } defer s.Close() return s.Start() }
func (ws *windowsService) Stop() error { m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(ws.Name) if err != nil { return err } defer s.Close() _, err = s.Control(svc.Stop) return err }
func StartService(name string) error { m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(name) if err != nil { return fmt.Errorf("winsvc.StartService: could not access service: %v", err) } defer s.Close() err = s.Start("p1", "p2", "p3") if err != nil { return fmt.Errorf("winsvc.StartService: could not start service: %v", err) } return nil }
func (r *SvcRunner) Start() error { if err := r.ValidateBeforeStart(); err != nil { log.Error(err.Error()) return err } r.startTime = time.Now() log.Infof("[%s] Starting (%s driver)", r.name, r.backend.Driver()) m, err := mgr.Connect() if err != nil { return backends.SetStatusLogErrorf(r.name, "Failed to connect to service manager: %v", err) } defer m.Disconnect() ws, err := m.OpenService(r.serviceName) if err != nil { return backends.SetStatusLogErrorf(r.name, "Could not access service: %v", err) } defer ws.Close() err = ws.Start("is", "manual-started") if err != nil { return backends.SetStatusLogErrorf(r.name, "Could not start service: %v", err) } r.isRunning = true go func() { for { time.Sleep(10 * time.Second) if r.isRunning && !r.Running() { backends.SetStatusLogErrorf(r.name, "Backend crashed, sending restart signal") r.Start() break } if !r.isRunning { break } } }() r.backend.SetStatus(backends.StatusRunning, "Running") return err }
func startService(name string) error { m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(name) if err != nil { return fmt.Errorf("could not access service: %v", err) } defer s.Close() err = s.Start("is", "manual-started") if err != nil { return fmt.Errorf("could not start service: %v", err) } return nil }
func TestOpenLanManServer(t *testing.T) { m, err := mgr.Connect() if err != nil { t.Fatalf("SCM connection failed: %s", err) } defer m.Disconnect() s, err := m.OpenService("LanmanServer") if err != nil { t.Fatalf("OpenService(lanmanserver) failed: %s", err) } defer s.Close() _, err = s.Config() if err != nil { t.Fatalf("Config failed: %s", err) } }
func startService(name string) error { log.Info("Starting Service") m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(name) if err != nil { return fmt.Errorf("could not access service: %v", err) } defer s.Close() err = s.Start("service") if err != nil { return fmt.Errorf("could not start service: %v", err) } log.Info("Service started") return nil }
func unregisterService() error { m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(*flServiceName) if err != nil { return err } defer s.Close() eventlog.Remove(*flServiceName) err = s.Delete() if err != nil { return err } return nil }
func (w *windowsJobSupervisor) Processes() ([]Process, error) { stdout, _, _, err := s.cmdRunner.RunCommand("powershell", "-noprofile", "-noninteractive", "/C", listAllJobsScript) if err != nil { return nil, bosherr.WrapError(err, "Listing windows job process") } m, err := mgr.Connect() if err != nil { return nil, err } defer m.Disconnect() var procs []Process lines := strings.Split(stdout, "\n") for i := 0; i < len(lines)-1; i += 2 { name := strings.TrimSpace(lines[i]) if name == "" { continue } _ = lines[i+1] // pid string service, err := m.OpenService(name) if err != nil { return nil, bosherr.WrapErrorf(err, "Opening windows service: %q", name) } defer service.Close() st, err := service.Query() if err != nil { return nil, bosherr.WrapErrorf(err, "Querying windows service: %q", name) } p := Process{ Name: name, State: SvcStateString(st.State), } procs = append(procs, p) } return procs, nil }
func removeService(name string) error { m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(name) if err != nil { return fmt.Errorf("service %s is not installed", name) } defer s.Close() err = s.Delete() if err != nil { return err } err = eventlog.Remove(name) if err != nil { return fmt.Errorf("RemoveEventLogSource() failed: %s", err) } return nil }
func (r *SvcRunner) Running() bool { m, err := mgr.Connect() if err != nil { backends.SetStatusLogErrorf(r.name, "Failed to connect to service manager: %v", err) } defer m.Disconnect() s, err := m.OpenService(r.serviceName) // service exist so we only update the properties if err != nil { backends.SetStatusLogErrorf(r.name, "Can't get status of service %s cause it doesn't exist: %v", r.serviceName, err) } defer s.Close() status, err := s.Query() if err != nil { backends.SetStatusLogErrorf(r.name, "Can't query status of service %s: %v", r.serviceName, err) } return status.State == svc.Running }
func (ws *windowsService) Uninstall() error { m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(ws.Name) if err != nil { return fmt.Errorf("service %s is not installed", ws.Name) } defer s.Close() err = s.Delete() if err != nil { return err } err = eventlog.Remove(ws.Name) if err != nil { return fmt.Errorf("RemoveEventLogSource() failed: %s", err) } return nil }
func TestOpenLanManServer(t *testing.T) { m, err := mgr.Connect() if err != nil { if errno, ok := err.(syscall.Errno); ok && errno == syscall.ERROR_ACCESS_DENIED { t.Skip("Skipping test: we don't have rights to manage services.") } t.Fatalf("SCM connection failed: %s", err) } defer m.Disconnect() s, err := m.OpenService("LanmanServer") if err != nil { t.Fatalf("OpenService(lanmanserver) failed: %s", err) } defer s.Close() _, err = s.Config() if err != nil { t.Fatalf("Config failed: %s", err) } }
// Run the specified command on the service. func serviceCommand(name string) error { m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() s, err := m.OpenService(exec.ServiceName) if err != nil { return err } defer s.Close() switch name { case "remove": return s.Delete() case "start": return s.Start() case "stop": _, err := s.Control(svc.Stop) return err } return nil }
// Service Status endpoint, will return 200, 404 or 50x func StatusHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) service_name := vars["service"] log.Println("Checking:", service_name) m, err := mgr.Connect() if err != nil { log.Println("Bad Connection") w.WriteHeader(http.StatusInternalServerError) defer m.Disconnect() return } log.Println("Connected") s, err := m.OpenService(service_name) if err != nil { log.Println("Service not found") w.WriteHeader(http.StatusNotFound) defer m.Disconnect() return } state, err := s.Query() if err != nil { log.Println("Service is in unknown state") w.WriteHeader(http.StatusInternalServerError) defer m.Disconnect() return } log.Println("Service status:", state) if state.State == windows.SERVICE_RUNNING { fmt.Fprintf(w, "Service is running: %d", state) } else { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("Service is not running")) } }
func deleteService(c *cli.Context) { m, err := mgr.Connect() if err != nil { fmt.Printf("Failed to connect to service control manager: %s\n", err) os.Exit(1) } defer m.Disconnect() service, err := m.OpenService(lib.ConnectorName) if err != nil { fmt.Printf("Failed to open service: %s\n", err) os.Exit(1) } defer service.Close() err = service.Delete() if err != nil { fmt.Printf("Failed to delete service: %s\n", err) os.Exit(1) } fmt.Println("Service deleted successfully") }
func stopService(c *cli.Context) { m, err := mgr.Connect() if err != nil { fmt.Printf("Failed to connect to service control manager: %s\n", err) os.Exit(1) } defer m.Disconnect() service, err := m.OpenService(lib.ConnectorName) if err != nil { fmt.Printf("Failed to open service: %s\n", err) os.Exit(1) } defer service.Close() _, err = service.Control(svc.Stop) if err != nil { fmt.Printf("Failed to stop service: %s\n", err) os.Exit(1) } fmt.Printf("Service stopped successfully") }
func registerService() error { p, err := getServicePath() if err != nil { return err } m, err := mgr.Connect() if err != nil { return err } defer m.Disconnect() c := mgr.Config{ ServiceType: windows.SERVICE_WIN32_OWN_PROCESS, StartType: mgr.StartAutomatic, ErrorControl: mgr.ErrorNormal, DisplayName: "Docker Engine", } // Configure the service to launch with the arguments that were just passed. args := []string{"--run-service"} for _, a := range os.Args[1:] { if a != "--register-service" && a != "--unregister-service" { args = append(args, a) } } s, err := m.CreateService(*flServiceName, p, c, args...) if err != nil { return err } defer s.Close() err = eventlog.Install(*flServiceName, p, false, eventlog.Info|eventlog.Warning|eventlog.Error) if err != nil { return err } return nil }