Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propagate windows service start parameters #82

Open
2opremio opened this issue Feb 19, 2017 · 15 comments
Open

Propagate windows service start parameters #82

2opremio opened this issue Feb 19, 2017 · 15 comments

Comments

@2opremio
Copy link

2opremio commented Feb 19, 2017

This library simply ignores and doesn't propagate the start parameters of windows services.

Those live parameters are very convenient and flexible, allowing to avoid configuration files or registry keys to store the parameters.

Related to #75

@2opremio
Copy link
Author

2opremio commented Feb 19, 2017

A new method (e.g. Args() []string) could be added to Service without breaking backwards compatibility.

Would you be interested in a PR?

@2opremio
Copy link
Author

2opremio commented Feb 19, 2017

The Start() method should also pass the arguments (and that one is tricky to change without breaking backwards compatibility)

@kardianos
Copy link
Owner

Are the args passed into Execute different then os.Args()?

@2opremio
Copy link
Author

2opremio commented Feb 20, 2017

Yes, Windows seems to distinguish between:

  • The arguments (os.Args()) passed to the Service Application binary managing services
  • The arguments (provided by windows/svc.Execute()) passed to a service on start.

AFAIU the arguments passed to Execute() are the ones provided to StartService (from advapi.dll)

As an example, both sc.exe and the Services UI let you pass those arguments on start:

$ sc.exe start
DESCRIPTION:
        Starts a service running.
USAGE:
        sc <server> start [service name] <arg1> <arg2> ...
The following WinRM command responded with a non-zero exit status.

screen shot 2017-02-20 at 19 46 30

Note that, in the last example you are free to choose service start arguments different from the ones passed to the binary (-k netsvcs)

@zhengxiaoyao0716
Copy link

@kardianos I got the problem too.
First, when I run my code with go run, it works correctly:
image
The first two line print by fmt, execute before service start.
The other print by log, witch would redirect to log file in service mode.

However, when I run my code with builded binary executer, the problem appeared:
image
image
You can see that fmt print the os.Args correctly, while log missing them.

@rgl
Copy link

rgl commented Aug 19, 2017

Any news about this? Something like what @2opremio proposed would be really nice to have :-)

@rgl
Copy link

rgl commented Aug 19, 2017

Oh, we can already manually propagate arguments! Sorry about the noise...

I ended up using something like:

	nameFlag := flag.String("name", "dummy", "Service name.")
	flag.Parse()
	s, err := service.New(
		&dummyService{},
		&service.Config{
			Arguments:   []string{"-name", *nameFlag},
			Name:        *nameFlag,
			DisplayName: "Dummy Windows Service",
			Description: "Dummy Windows Service",
		})

@jonathan-automox
Copy link

Can this technique of passing arguments be used to say create a "Delayed" start service?

@kardianos
Copy link
Owner

Yes.

@chuanbozhang-okta
Copy link

Oh, we can already manually propagate arguments! Sorry about the noise...
&service.Config{
Arguments: []string{"-name", *nameFlag},
})

@rgl , does this example actually propagate the live argument as @2opremio called out?
And how to access this parameters from the actual service start method when the parameter not passed through executable but through sc.exe or service control manager?

@chuanbozhang-okta
Copy link

chuanbozhang-okta commented Jun 26, 2020

I did more investigation, and see adding a line of ws.Arguments = append(ws.Arguments, args...) in Execute method of service_windows.go solved the issue for me.

func (ws *windowsService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (bool, uint32) {
	const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
	changes <- svc.Status{State: svc.StartPending}
	ws.Arguments = append(ws.Arguments, args...)	

then in my usage, I declare service.Config to my program struct, and then in program Start method access the parameter from p.config.Arguments, and I've validated that could propagate the live arguments from service control manager.

@kardianos , how do you feel this solution?

@msays2000
Copy link

msays2000 commented Jul 28, 2020

@chuanbozhang-okta @kardianos @rgl Is support for runtime arguments like below supported in windows service start method?

sc start serviceName arg1 arg2 ... argN

to be explicit when a customer starts the service with a runtime port number, I need to access this runtime parameter somehow or injected somhow.

sc start MyGrpcService runtimePortNumber

@chuanbozhang-okta
Copy link

@msays2000 , yes, my proposal fix above to add "ws.Arguments = append(ws.Arguments, args...)" to Execute method could fix the issue and make your usage work.

@kardianos , do you accept contribution for this? If so I could send a PR for it.

@msays2000
Copy link

@chuanbozhang-okta thank you for confirming.
@kardianos please review and help in merging the above PR of @chuanbozhang-okta

We have a use case where we need to start a grpc service on a determined port passed to the service via its start arguments.

@msays2000
Copy link

@kardianos is there an alternative to pass the arguments to a service.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants