1 package main // import "vimagination.zapto.org/academy-chauffeurs/updater" 2 3 import ( 4 "bufio" 5 "flag" 6 "fmt" 7 "io" 8 "net/http" 9 "os" 10 "path" 11 "time" 12 13 "github.com/cheggaaa/pb" 14 "golang.org/x/sys/windows/svc" 15 "golang.org/x/sys/windows/svc/mgr" 16 ) 17 18 var ( 19 executeablePath = flag.String("exe", "c:\\ac\\academy-chauffeurs.exe", "path to executeable") 20 serviceName = flag.String("svc", "Academy Chauffeurs", "service name") 21 url = flag.String("url", "http://vimagination.zapto.org/ac.exe", "update url") 22 ) 23 24 func Err(err error) bool { 25 if err != nil { 26 fmt.Println(err) 27 r := bufio.NewReader(os.Stdin) 28 r.ReadString('\n') 29 return true 30 } 31 return false 32 } 33 34 func main() { 35 flag.Parse() 36 fname := path.Clean(*executeablePath) 37 /*_, err := os.Stat(fname) 38 if os.IsNotExist(err) { 39 Err(errors.New("executable not found")) 40 return 41 }*/ 42 m, err := mgr.Connect() 43 if Err(err) { 44 return 45 } 46 defer m.Disconnect() 47 s, err := m.OpenService(*serviceName) 48 if Err(err) { 49 return 50 } 51 status, err := s.Query() 52 if Err(err) { 53 return 54 } 55 switch status.State { 56 case svc.StopPending: 57 fmt.Println("Waiting for service to stop") 58 time.Sleep(5 * time.Second) 59 fmt.Println("...done waiting") 60 case svc.Stopped: 61 default: 62 fmt.Println("Stopping service...") 63 _, err = s.Control(svc.Stop) 64 if Err(err) { 65 return 66 } 67 time.Sleep(5 * time.Second) 68 fmt.Println("...service stopped") 69 } 70 defer s.Start() 71 resp, err := http.Get(*url) 72 if Err(err) { 73 return 74 } 75 defer resp.Body.Close() 76 f, err := os.Create(fname + ".new") 77 if Err(err) { 78 return 79 } 80 fmt.Println("Downloading...") 81 bar := pb.New64(resp.ContentLength).SetUnits(pb.U_BYTES) 82 bar.Start() 83 w := io.MultiWriter(f, bar) 84 _, err = io.Copy(w, resp.Body) 85 f.Close() 86 if Err(err) { 87 os.Remove(fname + ".new") 88 return 89 } 90 bar.FinishPrint("...done") 91 Err(os.Remove(fname)) 92 Err(os.Rename(fname+".new", fname)) 93 }