在Windows上正常终止进程

时间:2019-03-10 20:35:10

标签: windows go service process

我正在用Go编写服务器应用程序,并使用包装程序将其作为Windows服务运行。

有必要正常关闭服务器(以正确关闭资源和连接),在UNIX中,它将通过SIGTERM信号进行处理。没什么。

尽管在Windows上情况似乎大不相同。我在this guide上看到信号实际上存在于窗口(?)上,并且定义了SIGTERM,尽管其他页面指示they don't,或使用诸如WM_CLOSE之类的其他机制。

告诉无头程序正常终止的最佳方法是什么?该如何在Go中实现?

服务器被设计为多平台的,因此最好采用最标准的方式。

4 个答案:

答案 0 :(得分:2)

信号在Windows上实现,但Unix信号不可用。 在golang的信号包中,有一个example,供Windows发送Ctrl-Break。重构它以进行交互使用here

答案 1 :(得分:1)

所以,过了一会儿,我只想分享我的解决方法。这很丑陋,但这是我发现的唯一真实方法。 Windows golang程序确实会侦听CTRL + C,这不是一个信号或类似的信号,但是它会使用与UNIX相同的信号触发go程序中的正常关机。

以下是相关代码:

// Create shutdown channel
exitChan := make(chan int)
interruptChan := make(chan os.Signal, 1)
signal.Notify(interruptChan, os.Interrupt)
select {
case exitCode := <-exitChan:
    os.Exit(exitCode)
case <-interruptChan:
    // This works in Windows if ctrl-c is invoked. It sucks though
    svr.Stop()
    os.Exit(-1)
}

要触发给定进程的CTRL + C,我使用了一个名为windows-kill.exe的小程序。

// Windows is "special" and we need to use a library for killing processes gracefully
// Unfortunately setting up the C++ library with go is a hassle, so we resort to a CLI tool
ex, _ := os.Executable()
cmdPath := filepath.Join(filepath.Dir(ex), "windows-kill.exe")
cmd := exec.CommandContext(context.Background(), cmdPath, "-SIGINT", strconv.Itoa(l.proc.Pid))

err := cmd.Start()
if err != nil {
    panic(err)
}

这是库和工具的仓库:https://github.com/alirdn/windows-kill

答案 2 :(得分:1)

在Windows上使用* nix构造和函数的想法通常是不好的,并且容易产生奇怪的诡计,这些诡计可能有效也可能无效。

关闭GUI应用程序时清除的正确方法是处理WM_QUERYENDSESSIONWM_ENDSESSION。 另外,您在通用关闭机制上具有灵活性,请检查here

如果您是服务,则获得通知的正确方法是控制台应用程序的服务处理程序(SERVICE_STOPPED)。有关更多信息,请参见Writing a ServiceMain

答案 3 :(得分:0)

如果您正在运行某种形式的Web服务,则最好使用Web服务本身来启动关闭,因为跟踪信号的PIDS可能会变得混乱。

要停止http网络服务,只需添加以下路由:

http.HandleFunc("/shutdown",
        func(w http.ResponseWriter, r *http.Request) {
            // stops server - may want to add admin credentials check here!
            srv.Shutdown(context.Background())
        })

操场source-code示例。

2019/03/10 16:58:15 Listening on: :8080

$ curl 'localhost:8080/shutdown'

2019/03/10 17:04:17 Listening on: :8080
2019/03/10 17:04:19 exited cleanly