package main import ( "context" "fmt" "github.com/wailsapp/wails/v2/pkg/runtime" "golang.org/x/sys/windows/registry" "os" "os/exec" "path/filepath" "strings" ) type HomeEvent struct { ctx context.Context } func NewHomeEvent() *HomeEvent { return &HomeEvent{} } func (a *HomeEvent) startup(ctx context.Context) { a.ctx = ctx } func (a *HomeEvent) ListWorkspace() *Dto { dirs := GetWorkspaceDirs() return SuccessDto(dirs) } func (a *HomeEvent) AddWorkspace(name string) *Dto { runtime.LogInfo(a.ctx, "创建工作空间: "+name) dataDir := GetDataDir() workspaceDir := filepath.Join(dataDir, name) _, err := os.Stat(workspaceDir) if os.IsExist(err) { return FailDto("目录已存在", nil) } err = os.Mkdir(workspaceDir, os.ModePerm) if err != nil { return FailDto("创建目录失败", err) } runtime.LogInfo(a.ctx, "创建工作空间成功: "+name) runtime.LogInfo(a.ctx, "创建默认配置文件: "+name) newConf := &WorkspaceConf{ BrowserPath: "", BrowserType: "", Workspace: name, } pathDto := a.GetDefaultBrowserPath() if pathDto.IsSuccess() { path := pathDto.Data.(string) newConf.BrowserPath = path // 通过路径是否为chrome.exe结尾 if strings.HasSuffix(path, "chrome.exe") { newConf.BrowserType = "chrome" } else if strings.HasSuffix(path, "firefox.exe") { newConf.BrowserType = "firefox" } else if strings.HasSuffix(path, "msedge.exe") { newConf.BrowserType = "edge" } } newConfInfo := fmt.Sprintf("默认配置: BrowserPath -> %v, BrowserType -> %v, Workspace -> %v", newConf.BrowserPath, newConf.BrowserType, newConf.Workspace) runtime.LogInfo(a.ctx, newConfInfo) newConf.WriteToFile() return SuccessDto(nil) } func (a *HomeEvent) GetCurrWorkspace() *Dto { config := GetConfig() workspace := config.LastWorkspace return SuccessDto(workspace) } func (a *HomeEvent) SetCurrentWorkspace(workspace string) *Dto { SetWorkSpace(workspace) return SuccessDto("") } func (a *HomeEvent) LoadCurrWorkspaceConf() *Dto { currWorkConf := GetCurrWorkspaceConf() return SuccessDto(currWorkConf) } func (a *HomeEvent) LoadBrowserConf() *Dto { config := GetConfig() path := config.Path if path != "" { return SuccessDto(path) } dto := a.GetDefaultBrowserPath() if !dto.IsSuccess() { dto = a.SelectPath("") } if dto.IsSuccess() { SetPath(dto.Data.(string)) } return dto } func (a *HomeEvent) GetDefaultBrowserPath() *Dto { keyPath := `Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.html\UserChoice` key, err := registry.OpenKey(registry.CURRENT_USER, keyPath, registry.QUERY_VALUE) if err != nil { return FailDto("无法打开注册表项: "+keyPath, err) } defer key.Close() progId, _, err := key.GetStringValue("Progid") if err != nil { return FailDto("无法获取注册表值: "+progId, err) } fmt.Println("获取注册表值成功, Progid -> {}", progId) commandKeyPath := progId + `\shell\open\command` commandKey, err := registry.OpenKey(registry.CLASSES_ROOT, commandKeyPath, registry.QUERY_VALUE) if err != nil { return FailDto("无法打开注册表项: "+commandKeyPath, err) } defer commandKey.Close() command, _, err := commandKey.GetStringValue("") if err != nil { return FailDto("无法读取注册表值: "+command, err) } fmt.Printf("读取注册表成功: 默认浏览器命令: %v\n", command) args := splitCommandLine(command) fmt.Println("命令解析结果: {}", args) command = args[0] command = strings.Trim(command, "\"") return SuccessDto(command) } func (a *HomeEvent) SelectPath(curr string) *Dto { currPath := "." currName := "" if curr != "" { currPath = filepath.Dir(curr) currName = filepath.Base(curr) } path, err := runtime.OpenFileDialog(a.ctx, runtime.OpenDialogOptions{ DefaultDirectory: currPath, DefaultFilename: currName, Filters: []runtime.FileFilter{ { DisplayName: "可执行程序", Pattern: "*.exe", }, }, }) if err != nil { return FailDto("选择文件失败", err) } SetBrowserPath(path) return SuccessDto(path) } func (a *HomeEvent) ChangeBrowserType(browserType string) *Dto { SetBrowserType(browserType) return SuccessDto("") } func (a *HomeEvent) ListInstance() *Dto { dirs := GetInstanceDirs() return SuccessDto(dirs) } func (a *HomeEvent) AddInstance(name string) *Dto { dataDir := GetDataDir() workspace := GetCurrWorkspace() _, err := os.Stat(filepath.Join(dataDir, workspace, name)) if os.IsExist(err) { return FailDto("实例已存在", nil) } err = os.Mkdir(filepath.Join(dataDir, workspace, name), os.ModePerm) if err != nil { return FailDto("创建实例失败", err) } return SuccessDto(nil) } func (a *HomeEvent) StartInstance(name string) *Dto { conf := GetCurrWorkspaceConf() browserPath := conf.BrowserPath browserType := conf.BrowserType if browserPath == "" { return FailDto("请选择浏览器可执行路径", nil) } _, err := os.Stat(browserPath) if os.IsNotExist(err) { return FailDto("可执行程序不存在", nil) } dataDir := GetDataDir() workspace := GetCurrWorkspace() instancePath := filepath.Join(dataDir, workspace, name) var arg []string if browserType == "chrome" { arg = append(arg, "--user-data-dir="+instancePath) } else if browserType == "edge" { arg = append(arg, "--user-data-dir="+instancePath) } else if browserType == "firefox" { arg = append(arg, "--profile", instancePath) } else { return FailDto("不支持的浏览器类型", nil) } runInfo := fmt.Sprintf("浏览器路径: %s, 启动参数: %s", browserPath, arg) runtime.LogInfo(a.ctx, runInfo) cmd := exec.Command(browserPath, arg...) //cmd.Stdout = os.Stdout //cmd.Stderr = os.Stderr //cmd.Stdin = os.Stdin err = cmd.Start() if err != nil { runtime.LogError(a.ctx, "启动浏览器失败: "+err.Error()) return FailDto("启动浏览器失败", err) } runtime.LogInfo(a.ctx, "启动浏览器成功") return SuccessDto(nil) }