Как я могу сделать программу Go, которая может удалить себя? - PullRequest
2 голосов
/ 14 апреля 2019

Все началось, когда я хотел создать программу, которая могла бы обновляться сама.Я решил, что мне нужна программа, чтобы загрузить новую версию и запустить функцию, которая копирует новую программу и заменяет оригинал загруженной версией.

Я пытался сделать эту проблему как можно меньше, как я могу сделатьпрограмма, которая вызывает другую программу для удаления самой себя, вот моя попытка:

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

Итак, в итоге: Какя могу создать программу, которая может удалить себя самостоятельно или с помощью второй команды / программы?

Бонус, если она переносима на другие операционные системы.

Ответы [ 2 ]

1 голос
/ 15 апреля 2019

Поскольку ваша цель состоит в том, чтобы приложение само обновлялось, я бы переместил эту функцию во второе приложение "средства обновления".В противном случае исполняемый файл (в зависимости от ОС) может быть заблокирован, плюс у вас все еще остается проблема перезапуска приложения.Поток будет выглядеть следующим образом:

  • основная программа вызывает программу обновления и завершает себя
  • программа обновления ожидает завершения основной программы
  • программа обновления заменяет исполняемый файл и перезапускает приложение (при желании)
0 голосов
/ 17 апреля 2019

Итак, примером того, как я могу решить эту проблему, которая работает в 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, чтобы удалить себя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...