-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: x/sys/windows/svc: Call AllocConsole as part of Run #72884
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
Comments
CC @golang/windows |
Why you cannot run AllocConsole API before you start your service?
I think what you are doing is pretty unusual, because average windows service does not interact with logged in user. Whole point of the service is to run without user logged in. But I am not a Windows expert enough to decide if adding AllocConsole to the begging of this code is a problem or not. Perhaps other users will help.
I don't think this feature is important enough to warrant new option that every user need to understand. But others might disagree.
You don't need a proposal. If you want to add AllocConsole Windows API to the Alex |
I can do so, and that is my solution at the moment, but it's not an obvious thing to have to do, and I thought if there was no downside to the svc package doing it automatically it would save folks some headache in the future.
Users programs interact with the service via an RPC interface. This is fairly standard, based on both MSDN docs and questions people ask online 0 1 2 3. The unusual part is that the service is spawning and managing its own child processes, which is something I've found very little precedent for, except for that one thread I linked in the OP.
I also don't know if this warrants an API change, which is why I listed it as a secondary option. IMO the package calling AllocConsole automatically would be much more preferable, if there's no downside to doing so.
Sounds good, will do so :) |
Good.
You are the first who complained about this problem. So your situation is not very common. I don't think that adding more code will "improve" the situation - new code needs to be maintained by the Go team. Alex |
As a longtime Windows dev who has written several services, I will tell you this: the usual way to control services like you are trying to do is not to emulate SIGINT but to use a Win32 Event (CreateEvent/SetEvent) both when running as a service AND when running as a console. C style events (SIGINT, etc) are second class citizens in Windows. You will be much happier with the Win32 IPC primitives: Events, Mutexes, etc. |
@ssexton71 unfortunately the child services I'm working with are not themselves written for windows, but for unix (but with windows support). So they don't set up windows event handlers like you describe, but do respond to the C-style events, so that's the avenue I'm taking to send them a simple shutdown message. |
That is your choice ofc. I was just trying to add some color since there seemed to be some q as to whether your approach based on Unix signal handlers is typical of a Windows service. It isn't. CreateEvent/SetEvent/WaitForMultipleObjects is. Idk if WFMO plays nice with goroutines though, since it blocks the thread. Note this isnt the same as a WIndows GUI event loop. It is more like a semaphore with a max value of 1. So not a lot to set up but it will tie up a thread. |
Proposal Details
Background
I am implementing a windows service which act as a kind of process manager; based on user input during its lifetime the service process will spawn its own child processes (with the CREATE_NEW_PROCESS_GROUP flag set), and based on other user input the service may decide to shut down those child processes using
windows.GenerateConsoleCtrlEvent(syscall.CTRL_BREAK_EVENT, pid)
. This control event acts more or less like a SIGINT in windows world.When running the process as an actual service, via the Windows Service Manager, I use svc.Run to make all the necessary system calls and process control messages.
When running the service from console the GenerateConsoleCtrlEvent works fine. However, when being run as a service, the GenerateConsolCtrlEvent returns the error
The handle is invalid.
. This is apparently because when running a process as a service windows does not allocate a console for the process.Adding the following into my Handler's Execute method fixes the problem:
Loading the DLL manually is necessary because
AllocConsole
is not exposed viax/sys/windows
.I discovered that AllocConsole would solve this issue based on this 20 year old thread from CodeGuru.
Proposal
I propose that svc.Run should call AllocConsole itself, perhaps just after the call to RegisterServiceCtrlHandlerEx. I am not a professional windows developer so I could well be mistaken, but I don't believe there's any reason to not allocate a console, and doing so would save other users from having to dig up this odd requirement in the future.
If there is a reason why someone would not want their service to have a console attached then perhaps a new function,
RunOpt
, could be introduced to the package. Something like:The
AllocConsole
field could specifically document why a console allocation would be desired, which would expose this possible edge-case to the user.Secondary Proposal: Expose AllocConsole in
x/sys/windows
I don't know what the process is for adding new syscalls to
x/sys/windows
, but having AllocConsole exposed there would be convenient.The text was updated successfully, but these errors were encountered: