Files
cdp_hub/internal/platform/files/executable_picker_windows.go
T

55 lines
1.7 KiB
Go

//go:build windows
package files
import (
"context"
"fmt"
"path/filepath"
"strings"
)
type windowsExecutablePicker struct{ runner commandRunner }
func NewExecutablePicker() ExecutablePicker { return windowsExecutablePicker{runner: execRunner{}} }
func newExecutablePickerWithRunner(runner commandRunner) windowsExecutablePicker {
return windowsExecutablePicker{runner: runner}
}
func (p windowsExecutablePicker) ChooseExecutable(ctx context.Context) (string, error) {
if err := ctx.Err(); err != nil {
return "", err
}
output, err := p.runner.Run(ctx, "powershell.exe",
"-NoProfile", "-NonInteractive", "-STA", "-WindowStyle", "Hidden", "-Command", executableDialogScript)
if err != nil {
if ctxErr := ctx.Err(); ctxErr != nil {
return "", ctxErr
}
return "", fmt.Errorf("open executable picker: %w", err)
}
selected := strings.TrimSpace(string(output))
if selected == "" {
return "", ErrSelectionCanceled
}
if !filepath.IsAbs(selected) {
return "", fmt.Errorf("executable picker returned a non-absolute path")
}
if !strings.EqualFold(filepath.Ext(selected), ".exe") {
return "", fmt.Errorf("executable picker returned a non-executable path")
}
return filepath.Clean(selected), nil
}
const executableDialogScript = `[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)
Add-Type -AssemblyName System.Windows.Forms
$dialog = New-Object System.Windows.Forms.OpenFileDialog
$dialog.Title = '选择 Chrome 或 Edge 可执行文件'
$dialog.Filter = '浏览器可执行文件 (*.exe)|*.exe|所有文件 (*.*)|*.*'
$dialog.CheckFileExists = $true
$dialog.Multiselect = $false
if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
[Console]::Out.Write($dialog.FileName)
}`