这一切都始于我想制作一个可以自我更新的程序。我想我需要程序下载新版本并运行一个复制新程序的功能,并用下载的版本替换原件。
我试图让这个问题尽可能小,我怎么能让一个程序调用另一个程序来删除自己,这是我的尝试:
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\n", 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\n", err)
}
}
}
以下是我通过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
总而言之:如何创建一个可以自行删除或通过第二个命令/程序删除自己的程序?
如果可以移植到不同的操作系统,可以获得奖励。
由于您的目标是让应用程序自行更新,因此我将此功能转移到第二个“更新程序”应用程序中。可执行文件(取决于操作系统)可能会被锁定,否则您仍然会遇到重新启动应用程序的问题。流程将是这样的:
因此,我可以在Mac OS,Linux和Windows上解决此问题的示例如下所示。
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\n", 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\n", err)
}
}
fmt.Println("Finished running program")
}
如果您像这样运行它,该程序将自行删除
uberswe$ go build -o test
uberswe$ go build -o remove
uberswe$ ./test
在Windows上我不得不做一个更改,即添加.exe扩展名,以便windows cmd将二进制文件识别为可执行文件。我能够使应用程序test
调用remove
删除自己。