如何验证父进程是否已在Windows上的golang中退出?

时间:2014-08-02 12:19:10

标签: windows winapi go synchronization

所以我正在编写一个小应用程序,它应该能够自行更新(替换它自己的二进制文件)。

在Windows上执行此操作的最佳方法似乎是:

  1. 将新版本的二进制文件下载为my.exe.new
  2. my.exes运行my.exe.new并退出
  3. my.exe.new等待my.exe退出
  4. my.exe.new将自身复制为my.exe
  5. my.exe.new将自己的另一个副本作为my.exe启动并退出
  6. my.exe等待my.exe.new退出
  7. my.exe删除my.exe.new
  8. 现在,要使所有这些工作,我必须能够同步进程之间的状态(能够知道父进程何时退出),但似乎golang Windows中的os.Getppid(也不是syscall.Getppid)没有实现,因为它总是返回-1。

    我已经看到补丁正在进行中,但我不愿意修补我的标准库。

    是否有一种简单的方法可以让Getppid处理更旧版本的Go(可能重新实现它?),或者也许任何人都可以提出一种更好的方法来同步进程状态?

    想到的东西是绑定套接字,但这是一个很大的hacky。

    也许将管道传递给子进程,并且子进程等待管道关闭?

    由于

2 个答案:

答案 0 :(得分:2)

您可以将os.Stdinexec.Cmd一起使用,现在我无法访问窗口来测试这一点,但是同样的概念应该适用于那里:

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)
    }
}

答案 1 :(得分:1)

父进程可以将其PID传递给子进程。

您可以使用命令行参数或环境变量来执行此操作。