service icon indicating copy to clipboard operation
service copied to clipboard

The service did not respond to the start or control request in a timely fashion.HELP!!!!!

Open Yihsiwei opened this issue 1 year ago • 11 comments

Why can deleting ”Executable: "C:\\Windows\\System32\\cmd.exe"“ be successful Executable: "C:\\Windows\\System32\\cmd.exe" will result in error deletion:The service did not respond to the start or control request in a timely fashion.

package main

import (
	"log"
	"time"

	"github.com/kardianos/service"
)

func main() {
	serviceName := "MyService" 
	svcConfig := &service.Config{
		Name:        serviceName,
		DisplayName: "My Service",
		Description: "My Golang service running on Windows",
		Executable:  "C:\\Windows\\System32\\cmd.exe",
	}

	prg := &program{}

	s, err := service.New(prg, svcConfig)
	if err != nil {
		log.Fatal(err)
	}

	go s.Run()

	time.Sleep(time.Duration(10) * time.Second)

	err = s.Install()
	if err != nil {
		log.Fatalf("无法安装服务:%v", err)
	}
	log.Println("服务安装成功")

	// 启动服务
	err = s.Start()
	if err != nil {
		log.Fatalf("无法启动服务:%v", err)
	}
	log.Println("服务启动成功")
}

type program struct{}

func (p *program) Start(s service.Service) error {
	go p.run()
	return nil
}

func (p *program) run() {

}

func (p *program) Stop(s service.Service) error {

	return nil
}

Yihsiwei avatar Jul 04 '23 07:07 Yihsiwei

In your code, run() should block e.g. at last have an infinite loop (e.g. for {}) -- but ... i am also facing the same issue.

adrianosela avatar Sep 12 '23 21:09 adrianosela

I am ALSO facing the same issue. Neither s.Start() or s.Stop() call the respective (p *program) Start or (p *program) Stop functions s.Run() DOES call (p *program) Start but that does not result in a properly running service in Windows. Is there a work around to these issues? I have a feeling that this package does not really work.

brucealthompson avatar Mar 19 '24 01:03 brucealthompson

Hey @brucealthompson.

The issue you are facing is because on windows, the operating system will call the executable with some flags that your executable must respond to.

adrianosela avatar Mar 19 '24 01:03 adrianosela

The package does work. Here's some more info on how we solved the issue you are seeing and why it occurs: https://github.com/borderzero/border0-cli/blob/main/cmd/connector.go#L208-L234

Specifically this part (e.g. passing the service flag value to this library) https://github.com/borderzero/border0-cli/blob/main/cmd/connector.go#L224-L229

adrianosela avatar Mar 19 '24 01:03 adrianosela

@adrianosela Thanks for the quick response on this. I am looking at the code you referenced but am having a difficult time visualizing what exactly is needed to handle Windows service control messages based on this code. This looks like an important part of the puzzle: connectorStartCmd.Flags().StringVarP(&serviceFlag, "service", "s", "", "used to provide service actions e.g. start | stop | install | uninstall...") Do you know of a more stripped down code example that handles Windows service control messages?

brucealthompson avatar Mar 19 '24 02:03 brucealthompson

@brucealthompson

My understanding is for any windows service, the OS will invoke the service's executable with some value of "-service" to start it. And the executable must handle it. If the executable does not handle it by responding appropriately, the operating system will consider it unhealthy/not-started. Those are those "failed to respond" error messages you see.

I figured this library would handle control messages appropriately by calling the "Control" function in this library with the value of the flag.

I'm not a windows person and I didnt really dive into it as the above worked for me

adrianosela avatar Mar 19 '24 03:03 adrianosela

I think I get it now. My service application is already handling the -service flag but not all the verbs that go with it (like start and stop). I will try it.

brucealthompson avatar Mar 19 '24 03:03 brucealthompson

Well.... I spent a full day on this. I actually have a VERY similar service based on this same package and it works fine. I decided to reorganize code for both services so they are almost identical now. Same issue. One service works fine. The other gives an immediate timeout error. The error obviously has NOTHING to do with a timeout. Here is the code in the golang windows syscall package that fails: func StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) { r1, _, e1 := syscall.Syscall(procStartServiceW.Addr(), 3, uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors))) if r1 == 0 { err = errnoErr(e1) } return }

IMHO, there is clearly something wrong with kardianos/service having to do with its Windows implementation.

brucealthompson avatar Mar 20 '24 03:03 brucealthompson

Final word on this. I FINALLY got it all to work!!! kardianos/service DOES work with Windows The core of the issue for me is that there are MANY golang packages (for example "encoding/json") that end up putting the service executable into interactive mode. Windows will NOT start a service in interactive mode. It gives the cryptic error "The service did not respond to the start or control request in a timely fashion". What I would recommend is that kardianos/service checks if the application is in interactive mode in the windows implementation of service.Control(start) and give a non-cryptic error message. This will keep a lot of people from tearing their hair out when using this package for windows applications.

brucealthompson avatar Mar 24 '24 14:03 brucealthompson

Final word on this. I FINALLY got it all to work!!! kardianos/service DOES work with Windows The core of the issue for me is that there are MANY golang packages (for example "encoding/json") that end up putting the service executable into interactive mode. Windows will NOT start a service in interactive mode. It gives the cryptic error "The service did not respond to the start or control request in a timely fashion". What I would recommend is that kardianos/service checks if the application is in interactive mode in the windows implementation of service.Control(start) and give a non-cryptic error message. This will keep a lot of people from tearing their hair out when using this package for windows applications.

So do you know waht can i do to run the executable as service in Windows ?

buzzlightyear2k avatar Apr 23 '24 04:04 buzzlightyear2k

Final word on this. I FINALLY got it all to work!!! kardianos/service DOES work with Windows The core of the issue for me is that there are MANY golang packages (for example "encoding/json") that end up putting the service executable into interactive mode. Windows will NOT start a service in interactive mode. It gives the cryptic error "The service did not respond to the start or control request in a timely fashion". What I would recommend is that kardianos/service checks if the application is in interactive mode in the windows implementation of service.Control(start) and give a non-cryptic error message. This will keep a lot of people from tearing their hair out when using this package for windows applications.

So do you know waht can i do to run the executable as service in Windows ?

I ended up just creating a small service executable that issues os.Exec() on the executable that I want to run as a service.

brucealthompson avatar Apr 26 '24 13:04 brucealthompson