Description
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:
if r, _, err := windows.NewLazySystemDLL("kernel32.dll").NewProc("AllocConsole").Call(); r == 0 {
panic(err)
}
Loading the DLL manually is necessary because AllocConsole
is not exposed via x/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:
type RunOpts struct {
AllocConsole bool
}
func RunOpt(name string, handler Handler, opts RunOpts) error
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.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status