mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-05-07 06:22:57 +08:00
- 启动参数新增固定 WebviewUserDataPath 到 %APPDATA%/GoNavi/WebView2 - 首次启动自动迁移历史 WebView 数据目录 - 保留现有存储键,避免破坏已落盘配置 - 前端持久化读取增加历史结构兼容 - refs #125
124 lines
2.6 KiB
Go
124 lines
2.6 KiB
Go
//go:build windows
|
|
|
|
package main
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
func resolveWindowsWebviewUserDataPath() string {
|
|
appDataDir := strings.TrimSpace(os.Getenv("APPDATA"))
|
|
if appDataDir == "" {
|
|
return ""
|
|
}
|
|
|
|
targetDir := filepath.Join(appDataDir, "GoNavi", "WebView2")
|
|
_ = migrateLegacyWindowsWebviewUserData(appDataDir, targetDir)
|
|
return targetDir
|
|
}
|
|
|
|
func migrateLegacyWindowsWebviewUserData(appDataDir, targetDir string) error {
|
|
if dirHasContent(targetDir) {
|
|
return nil
|
|
}
|
|
|
|
exeName := "GoNavi.exe"
|
|
if exePath, err := os.Executable(); err == nil {
|
|
base := strings.TrimSpace(filepath.Base(exePath))
|
|
if base != "" {
|
|
exeName = base
|
|
}
|
|
}
|
|
exeBase := strings.TrimSuffix(exeName, filepath.Ext(exeName))
|
|
|
|
candidates := []string{
|
|
filepath.Join(appDataDir, exeName),
|
|
filepath.Join(appDataDir, exeBase),
|
|
filepath.Join(appDataDir, "GoNavi.exe"),
|
|
filepath.Join(appDataDir, "GoNavi"),
|
|
}
|
|
|
|
seen := make(map[string]struct{}, len(candidates))
|
|
for _, candidate := range candidates {
|
|
src := filepath.Clean(strings.TrimSpace(candidate))
|
|
if src == "" || strings.EqualFold(src, filepath.Clean(targetDir)) {
|
|
continue
|
|
}
|
|
key := strings.ToLower(src)
|
|
if _, exists := seen[key]; exists {
|
|
continue
|
|
}
|
|
seen[key] = struct{}{}
|
|
|
|
if !dirHasContent(src) {
|
|
continue
|
|
}
|
|
return copyDirTree(src, targetDir)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func dirHasContent(path string) bool {
|
|
info, err := os.Stat(path)
|
|
if err != nil || !info.IsDir() {
|
|
return false
|
|
}
|
|
entries, err := os.ReadDir(path)
|
|
return err == nil && len(entries) > 0
|
|
}
|
|
|
|
func copyDirTree(srcDir, dstDir string) error {
|
|
if err := os.MkdirAll(dstDir, 0o755); err != nil {
|
|
return err
|
|
}
|
|
|
|
return filepath.WalkDir(srcDir, func(srcPath string, d os.DirEntry, walkErr error) error {
|
|
if walkErr != nil {
|
|
return walkErr
|
|
}
|
|
relPath, err := filepath.Rel(srcDir, srcPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if relPath == "." {
|
|
return nil
|
|
}
|
|
dstPath := filepath.Join(dstDir, relPath)
|
|
|
|
if d.IsDir() {
|
|
return os.MkdirAll(dstPath, 0o755)
|
|
}
|
|
|
|
info, err := d.Info()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return copyFileWithMode(srcPath, dstPath, info.Mode())
|
|
})
|
|
}
|
|
|
|
func copyFileWithMode(srcPath, dstPath string, mode os.FileMode) error {
|
|
srcFile, err := os.Open(srcPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer srcFile.Close()
|
|
|
|
if err := os.MkdirAll(filepath.Dir(dstPath), 0o755); err != nil {
|
|
return err
|
|
}
|
|
dstFile, err := os.OpenFile(dstPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode.Perm())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer dstFile.Close()
|
|
|
|
if _, err := io.Copy(dstFile, srcFile); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|