2014-08-02 12:19
浏览 123


So I am writing a small utility which should be able to update itself (replace it's own binary).

The best way to do this on Windows seems to be:

  1. Download the new version of the binary as
  2. my.exes runs and exits
  3. waits for my.exe to exit
  4. copies itself as my.exe
  5. starts another copy of itself as my.exe and exits
  6. my.exe waits for to exit
  7. my.exe removes

Now for all of this to work I have to be able to synchronize the state between the processes (being able to know when the parent has exited), but it seems that os.Getppid (nor syscall.Getppid) in golang Windows is not implemented as it always returns -1.

I've seen that patches are underway, but I am not willing to patch my standard libraries.

Is there an easy way to make Getppid working on even older versions of Go (perhaps reimplementing it?), or perhaps anyone can suggest a better method of synchronizing between the process state?

The thing which comes to mind is binding on a socket, but thats a big hacky.

Perhaps passing a pipe to the child process, and the child waiting for the pipe to close?


图片转代码服务由CSDN问答提供 功能建议



  1. 将二进制文件的新版本下载为my.exe。 .new
  2. my.exes运行my.exe.new并退出
  3. my.exe.new等待my.exe退出 < li> my.exe.new将自身复制为my.exe
  4. my.exe.new将其自身的另一个副本复制为my.exe并退出
  5. my.exe 等待my.exe.new退出
  6. my.exe删除

    现在所有这些操作 工作,我必须能够同步进程之间的状态(能够知道父进程何时退出),但是在golang Windows中似乎未实现os.Getppid(也没有syscall.Getppid),因为它总是返回-1


    有一种简单的制作方法 Getppid甚至可以在旧版本的Go上工作(也许重新实现它?),或者也许有人可以建议一种更好的在进程状态之间进行同步的方法?


    也许将管道传递给子进程,而子进程正在等待管道 关闭?


  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • doulin2947 2014-08-02 23:54

    The parent process can pass its PID to the child.

    You could use a command-line parameter or an environment variable to do this.

    解决 无用
    打赏 举报
  • doukang2003 2014-08-02 17:36

    You could use os.Stdin with exec.Cmd, now I don't have access to windows to test this, however the same concept should apply there just fine:

    var child = flag.Bool("child", false, "damn children and their music")
    func init() {
    func main() {
        if *child {
            fmt.Println("child start", time.Now())
            // wait until the parent dies and bufio closes the stdin
            fmt.Println("the parent is dead", time.Now())
            time.Sleep(5 * time.Second)
        } 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)
    解决 无用
    打赏 举报

相关推荐 更多相似问题