doupingmao1903 2019-04-14 14:04
浏览 368
已采纳

我如何制作可以自行删除的Go程序?

This all started when I wanted to make a program that could update itself. I figured I need the program to download a new version and run a function that copies the new program and replaces the original with the downloaded version.

I tried to make this problem as small as possible, how can I make a program that calls another program to remove itself, here is my attempt:

package main

import (
    "flag"
    "fmt"
    "log"
    "os"
    "os/exec"
    "time"
)

func main()  {
    fmt.Println("program started")
    remove := flag.Bool("rm", false, "removes test")
    flag.Parse()

    if *remove {
        // Wait 5 seconds to let other program finish
        time.Sleep(5 * time.Second)
        // Try to remove program that started this program
        fmt.Println("running rm")
        err := os.Remove("./test")
        if err != nil {
            log.Fatalf("os.Remove() failed with %s
", err)
        }
    } else {
        // Call the second program which will remove ./test which is currently running
        fmt.Println("running remove program")
        cmd := exec.Command("./remove", "-rm")
        err := cmd.Start()
        if err != nil {
            log.Fatalf("cmd.Run() failed with %s
", err)
        }
    }
}

Here is how I call this via cli.

uberswe$ go build -o test
uberswe$ go build -o remove
uberswe$ ./test
program started
running remove program
uberswe$ ls -la
total 9048
drwxr-xr-x@  6 uberswe  staff      192 Apr 14 15:55 .
drwxr-xr-x@ 56 uberswe  staff     1792 Apr 14 15:36 ..
drwxr-xr-x@  6 uberswe  staff      192 Apr 14 15:55 .idea
-rw-r--r--@  1 uberswe  staff      680 Apr 14 15:55 main.go
-rwxr-xr-x@  1 uberswe  staff  2311528 Apr 14 15:55 remove
-rwxr-xr-x@  1 uberswe  staff  2311528 Apr 14 15:55 test

So in summary: How can I make a program that can remove itself either on its own or via a second command/program?

Bonus if it is portable to different operating systems.

  • 写回答

2条回答 默认 最新

  • doutang1856 2019-04-17 18:25
    关注

    So an example of how I can solve this which works on Mac OS, Linux and Windows is the following code.

    package main
    
    import (
        "flag"
        "fmt"
        "log"
        "os"
        "os/exec"
        "runtime"
        "time"
    )
    
    func main()  {
        fmt.Println("program started")
        remove := flag.Bool("rm", false, "removes test")
        flag.Parse()
    
        if *remove {
            var err error
            // Wait 5 seconds to let other program finish
            time.Sleep(5 * time.Second)
            // Try to remove program that started this program
            fmt.Println("running rm")
            if runtime.GOOS == "windows" {
                err = os.Remove("./test.exe")
            } else {
                err = os.Remove("./test")
            }
            if err != nil {
                log.Fatalf("os.Remove() failed with %s
    ", err)
            }
        } else {
            var cmd *exec.Cmd
            // Call the second remove program which will remove ./test which is currently running
            fmt.Println("running remove program")
            if runtime.GOOS == "windows" {
                cmd = exec.Command("./remove.exe", "-rm")
            } else {
                cmd = exec.Command("./remove", "-rm")
            }
            cmd.Stdout = os.Stdout
            cmd.Stderr = os.Stderr
            err := cmd.Start()
            if err != nil {
                log.Fatalf("cmd.Run() failed with %s
    ", err)
            }
        }
        fmt.Println("Finished running program")
    }
    

    This program will remove itself if you run it like so

    uberswe$ go build -o test
    uberswe$ go build -o remove
    uberswe$ ./test
    

    On windows I had to make one change which is to add the .exe extension in order for windows cmd to recognize the binary as an executable file. I was able to make the application test call on remove to delete itself.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料