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

x/sys/windows/svc: Failed to start windows service with Start Parameters #48227

Open
mshamn6x opened this issue Sep 7, 2021 · 17 comments
Open
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@mshamn6x
Copy link

mshamn6x commented Sep 7, 2021

What version of Go are you using (go version)?

$ go version
go version go1.14.14 windows/amd64

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Administrator\AppData\Local\go-build
set GOENV=C:\Users\Administrator\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\Administrator\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=c:\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\ADMINI~1\AppData\Local\Temp\2\go-build198320826=/tmp/go-build -gno-record-gcc-switches

What did you do?

Tried creating windows service for windows console application that runs webservice. Followed example from https://github.com/golang/sys/tree/master/windows/svc/example

Based on above example I'm able to install windows service using go. But when I try to start it with start parameter it is not working in expected way. I used following configuration for created windows service,

serviceConfig := mgr.Config{
	StartType:      mgr.StartManual,
	DisplayName:    name,
	Description:    desc,
	BinaryPathName: ExecutablePath,
	ServiceStartName: UserName,
	Password:         Password,
}

s, err = m.CreateService(name, w.ExecutablePath, serviceConfig, "init")
if err != nil {
	log.Errorf("Failed to create %s service due to %s", name, err)
	return err
}
defer s.Close()

I assume command line argument(start parameter) Added properly in service (init command appears with executable path so...), refer below image.

image

I programmed like whenever init is executed with that application, log will be written in log file. If I run that manually logs are properly updated. But with this windows service it is not working properly. Likewise I want to create webservice start/stop through windows service.

In above image "start parameter" field is also empty. Whether this is correct way of doing it ? If not please share examples.

What did you expect to see?

windows service with Start parameter would work properly.

What did you see instead?

Windows service with start parameter is not working properly.

@gopherbot gopherbot added this to the Unreleased milestone Sep 7, 2021
@thanm thanm added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Sep 7, 2021
@thanm
Copy link
Contributor

thanm commented Sep 7, 2021

@bradfitz
Copy link
Contributor

bradfitz commented Sep 7, 2021

I wasn't sure what that GUI field means, but found this answer: https://stackoverflow.com/a/42821528

@alexbrainman
Copy link
Member

@mshamn6x I don't know how to use Start parameters field on your picture.

I googled for it, and that is all I can find

https://forums.codeguru.com/showthread.php?251755-Passing-Parameters-to-Win32-Services

Also SERVICE_ACCEPT_PARAMCHANGE and SERVICE_CONTROL_PARAMCHANGE are probably related.

I would just use fields set in Path to executable field instead. And you know how to set and read them.

I wasn't sure what that GUI field means, but found this answer: https://stackoverflow.com/a/42821528

This refers to a C# solution. So I don't see how that is helpful. Unless you can find translation of that C# code into Win32 API.

Alex

@mshamn6x
Copy link
Author

mshamn6x commented Sep 8, 2021

@Ale thanks for the reply.

In registry by default command line argument is added properly in ImagePath field. As described in here, https://serverfault.com/a/143384/794689

Actually I followed all the mentioned methods in that thread. But none of them worked for me.

I even tried following but none of them working as expected.

net start <name of service> /parameter

sc start <name of service> parameter

Do you want me to add SERVICE_ACCEPT_PARAMCHANGE and SERVICE_CONTROL_PARAMCHANGE parameters like this ?

image

Do I need to change anything in this method https://github.com/golang/sys/blob/master/windows/svc/example/service.go#L23 ?

@alexbrainman
Copy link
Member

Do you want me to add SERVICE_ACCEPT_PARAMCHANGE and SERVICE_CONTROL_PARAMCHANGE parameters like this ?

No. I don't.

Do I need to change anything in this method https://github.com/golang/sys/blob/master/windows/svc/example/service.go#L23 ?

Why would I need you to change anything in that file?

Alex

@mshamn6x
Copy link
Author

mshamn6x commented Sep 9, 2021

Do I need to change anything in this method https://github.com/golang/sys/blob/master/windows/svc/example/service.go#L23 ?

Why would I need you to change anything in that file?

No not exactly that file, I'm asking do I need to modify this function in my source, to pass those arguments or something like that?

@alexbrainman
Copy link
Member

No not exactly that file, I'm asking do I need to modify this function in my source, to pass those arguments or something like that?

I do not know answer to your question.

Alex

@mshamn6x
Copy link
Author

Tried with following go version facing the same probelm.

# go version
go version go1.16.8 windows/amd64

@zx2c4
Copy link
Contributor

zx2c4 commented Sep 16, 2021

If you call s.Start("hello", "world"), then when the service runs, the args parameter of Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (svcSpecificEC bool, exitCode uint32) { will contain the name of the service, plus "hello" and "world".

@zx2c4
Copy link
Contributor

zx2c4 commented Sep 16, 2021

You were wondering about that GUI dialog. That GUI dialog also calls that same StartService function and passes it the parameters you place in the box. Those parameters are ephemeral. It is for that reason that the dialog uses the phrase "from here":

image

@mshamn6x
Copy link
Author

@zx2c4 Thank you for your reply on this.

startService() has only one argument right ? That is to pass service name to s.Start(). If you meant s.Start() then i'm fine with it.

Can you please kindly have look at this? I've created small code sample https://github.com/mshamn6x/go-windows-service

here I've created simple command line argument with service. Let's say If I run "exmaple.exe init" it will write some log.

And I tried to create windows service with this "init" parameter so whenever I starting this service it supposed to call this "init" argument , so that I expect log file should be updated, but it is not happening with this window service.

Please provide your comments on this.

@zx2c4
Copy link
Contributor

zx2c4 commented Sep 18, 2021

https://pkg.go.dev/golang.org/x/sys/windows/svc/mgr#Service.Start

Service.Start takes a variadic argument.

@mshamn6x
Copy link
Author

yes,

https://pkg.go.dev/golang.org/x/sys/windows/svc/mgr#Mgr.CreateService

CreateService installs new service name on the system. The service will be executed by running exepath binary. Use config c to specify service parameters. Any args will be passed as command-line arguments when the service is started; these arguments are distinct from the arguments passed to Service.Start or via the "Start parameters" field in the service's Properties dialog box.

I think in that source I used init parameters in both places

@zx2c4
Copy link
Contributor

zx2c4 commented Sep 18, 2021

I'm lost as to what the bug is that this issue is about. As far as I can tell, everything is working as expected? If so I believe you can close this? Or is there a subtlety I'm missing?

@mshamn6x
Copy link
Author

mshamn6x commented Sep 18, 2021

No issue is not yet resolved.

https://github.com/mshamn6x/go-windows-service

have you checked this repo ?

Steps to reproduce:

_```

  1. Clone and build this (https://github.com/mshamn6x/go-windows-service.git) source (go build) this will generate "example.exe"
  2. Run command "example.exe init" , this command will create logs.txt and log will be written like this "2021/09/18 03:36:46 Log called from init". Ensure the same.
  3. Run command "example.exe install" this command will install this executable as service. Name of service is "myservice".
  4. Open services and verify the same. Here service is created with command line argument "init".
  5. Open command prompt and change directory to "example.exe" executable file location.
  6. Now perform "example.exe stop". Ensure windows service is stopped and log file is updated with log "2021/09/18 03:42:15 Log called from stop" like this.
  7. Perform "example.exe start". Ensure windows service is started and log file is updated with log "2021/09/18 03:42:30 Log called from start" like this.
  8. Now open "services" and search for 'myservice' and ensure it is in running state.
  9. Right click on service and perform stop operation.
  10. Check log file and ensure log is not updated properly.
  11. Right click on service and perform start operation.
  12. Check log file and ensure log is not updated properly.
  13. Now stop the service and do right click -> properties
  14. In start parameter field Type "init" as start parameter and hit start button and ensure service is started and log file is not updated properly.

Expected result: If The service is started/stopped using windows service GUI. Log file should be updated properly but is it not being updated properly. Not only from the GUI. Even If I execute from command line like "example.exe start" init log and start log should be written in file. But only start log is written.

@zx2c4
Copy link
Contributor

zx2c4 commented Sep 18, 2021

I don't recognize a Go bug in that description. Seems like there's some confusion over log files vs event log or something now, but I'm still unclear on what the issue here, and unfortunately I don't think I'll be able to help more.

@mshamn6x
Copy link
Author

I want to create go executable that is command line argument style.
As of now it is working like this in Linux,
If I run webservice.exe initialize this will generate all log files and pointers.
If I run webservice.exe start it supposed to start http web-server, like wise webservice.exe stop stops the web service. I've created this as service in Linux, whenever this service starts I internally mapped <webservice.exe start> internally so that webservice will be started. So as stop and initialize. These all are working properly without any issue in Linux.

I need to support the same in windows. So I need to create windows service right? I started work with this package and I was able to deploy service and start stop are working without any issue. But this webservice start stop are not working properly.

If run manually webservice.exe start from command line then webservice is running. It should be like when I hit service start from services.exe I expect webservice should start properly. But with this windows service it is not working properly.

Can anyone add example with start parameter?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

6 participants