diff --git a/main.go b/main.go index 5207ea3..5de18a2 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "Win2Linux/pkg/windows" _ "embed" "fmt" "os" @@ -49,7 +50,10 @@ func onReady() { mCustom := systray.AddMenuItem(key, "Switch to"+key) go func() { <-mCustom.ClickedCh - fmt.Println(uuid) + if uuid == "{fwbootmgr}" { + rebootToFirmware() + return + } reboot(uuid) }() @@ -71,7 +75,7 @@ func list() []Entry { cmd := exec.Command("bcdedit", "/enum", "firmware") out, err := cmd.Output() if err != nil { - panic(err) + fatal(fmt.Sprintf("failed to run bcdedit: %s\n\nRun this program in administrator mode", err), 1) } return parse(string(out)) } @@ -122,13 +126,26 @@ func parse(out string) []Entry { } func reboot(uuid string) { - if err := exec.Command("bcdedit", "/Set", "{fwbootmgr}", "BootSequence", uuid, "/addFirst").Run(); err != nil { - panic(err) + out, err := exec.Command("bcdedit", "/Set", "{fwbootmgr}", "BootSequence", uuid, "/addFirst").Output() + if err != nil { + windows.MessageBox(windows.NULL, fmt.Sprintf("failed to execute bcdedit: %s", out), "Win2Linux", windows.MB_OK) + return } - if err := exec.Command("shutdown", "/r", "/t", "0").Run(); err != nil { - panic(err) + out, err = exec.Command("shutdown", "/r", "/t", "0").Output() + if err != nil { + windows.MessageBox(windows.NULL, fmt.Sprintf("failed to restart the computer: %s", out), "Win2Linux", windows.MB_OK) } - - os.Exit(0) +} + +func rebootToFirmware() { + out, err := exec.Command("shutdown", "/r", "/fw", "/t", "0").Output() + if err != nil { + windows.MessageBox(windows.NULL, fmt.Sprintf("failed to restart the computer: %s", out), "Win2Linux", windows.MB_OK) + } +} + +func fatal(message string, exitCode int) { + windows.MessageBox(windows.NULL, message, "Win2Linux", windows.MB_OK) + os.Exit(exitCode) } diff --git a/pkg/windows/windows.go b/pkg/windows/windows.go new file mode 100644 index 0000000..202cc3f --- /dev/null +++ b/pkg/windows/windows.go @@ -0,0 +1,30 @@ +package windows + +import ( + "syscall" + "unsafe" +) + +const ( + NULL = 0 + MB_OK = 0 +) + +// MessageBox of Win32 API. +func MessageBox(hwnd uintptr, caption, title string, flags uint) int { + _caption, err := syscall.UTF16PtrFromString(caption) + if err != nil { + panic(err) + } + _title, err := syscall.UTF16PtrFromString(title) + if err != nil { + panic(err) + } + ret, _, _ := syscall.NewLazyDLL("user32.dll").NewProc("MessageBoxW").Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(_caption)), + uintptr(unsafe.Pointer(_title)), + uintptr(flags)) + + return int(ret) +}