Files

54 lines
1.5 KiB
Go

//go:build !nogui
package gui
import (
"fmt"
"os"
"path/filepath"
"syscall"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/yetone/magpie/internal/proc"
)
// openFolder starts Explorer on the folder and leaves it to open: not on the
// window's thread, and not waited for, where Wails' own way holds the thread
// the windows are drawn on until Explorer is done and kills it after ten
// seconds.
func openFolder(_ *application.App, path string) error {
if _, err := os.Stat(path); err != nil {
return err
}
cmd := proc.Command(explorer())
if cmd.SysProcAttr == nil {
cmd.SysProcAttr = &syscall.SysProcAttr{}
}
// Explorer reads its own command line: the path quoted, not escaped as Go would
cmd.SysProcAttr.CmdLine = fmt.Sprintf(`explorer.exe "%s"`, path)
if err := cmd.Start(); err != nil {
return fmt.Errorf("explorer: %w", err)
}
go cmd.Wait() // it exits 1 when it did open the folder
return nil
}
// explorer is Explorer's own path: it isn't looked for on PATH, which an app
// started some ways (an updater's restart, a shortcut of another program's)
// can have without the Windows folder, and then "explorer.exe" isn't found.
func explorer() string {
for _, v := range []string{"SystemRoot", "windir"} {
if dir := os.Getenv(v); dir != "" {
if p := filepath.Join(dir, "explorer.exe"); fileExists(p) {
return p
}
}
}
return `C:\Windows\explorer.exe`
}
func fileExists(p string) bool {
_, err := os.Stat(p)
return err == nil
}