所以我正在编写一个小实用程序,它应该能够 self 更新(替换它自己的二进制文件)。
在 Windows 上执行此操作的最佳方法似乎是:
- 将新版本的二进制文件下载为 my.exe.new
- my.exes 运行 my.exe.new 并退出
- my.exe.new 等待 my.exe 退出
- my.exe.new 将自身复制为 my.exe
- my.exe.new 启动另一个自身副本作为 my.exe 并退出
- my.exe 等待 my.exe.new 退出
- my.exe 删除 my.exe.new
现在,要使所有这些工作正常进行,我必须能够同步进程之间的状态(能够知道父进程何时退出),但似乎 golang Windows 中的 os.Getppid (也不是 syscall.Getppid)未实现,因为它总是返回 -1。
我已经看到补丁正在进行中,但我不愿意修补我的标准库。
有没有一种简单的方法可以让 Getppid 在甚至更旧版本的 Go 上工作(也许重新实现它?),或者也许有人可以建议一种在进程状态之间同步的更好方法?
我想到的是绑定(bind)在套接字上,但这是一个大问题。
也许将管道传递给子进程,然后子进程等待管道关闭?
谢谢
最佳答案
您可以将 os.Stdin 与 exec.Cmd 一起使用,现在我无法访问 Windows 来测试它,但是相同的概念应该适用于此:
var child = flag.Bool("child", false, "damn children and their music")
func init() {
flag.Parse()
}
func main() {
if *child {
fmt.Println("child start", time.Now())
// wait until the parent dies and bufio closes the stdin
ioutil.ReadAll(os.Stdin)
fmt.Println("the parent is dead", time.Now())
time.Sleep(5 * time.Second)
fmt.Println("tada\n")
} else {
fmt.Fprintln(os.Stdout, time.Now())
cmd := exec.Command(os.Args[0], "-child")
cmd.Stdout = os.Stdout //not needed in a real program.
//this is important, bufio will close after the parent exits,
// unlike os.Stdin which screws up, at least on linux
cmd.Stdin = bufio.NewReader(os.Stdin)
fmt.Println("giving painful birth:", cmd.Start())
time.Sleep(2 * time.Second)
}
}
关于windows - 如何在 Windows 上的 golang 中验证父进程是否已退出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25094958/