Files
NetworkAuth/utils/path.go

65 lines
1.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package utils
import (
"os"
"path/filepath"
"strings"
)
// GetRootDir 获取当前程序运行的真实根目录
// 能够智能、跨平台地识别是编译后的可执行文件运行,还是通过 `go run` 运行(通常在临时目录下)
func GetRootDir() string {
var baseDir string
// 首先尝试获取当前工作目录
workDir, err := os.Getwd()
if err != nil {
workDir = "."
}
// 获取程序可执行文件所在目录
execPath, err := os.Executable()
if err != nil {
// 如果获取可执行文件路径失败,使用当前工作目录
return workDir
}
// 解析软链接获取真实物理路径macOS 下 /tmp 经常是 /private/tmp 的软链)
realExecPath, err := filepath.EvalSymlinks(execPath)
if err == nil {
execPath = realExecPath
}
execDir := filepath.Dir(execPath)
realTempDir, err := filepath.EvalSymlinks(os.TempDir())
if err != nil {
realTempDir = os.TempDir()
}
// 跨平台安全地判断 execDir 是否在 realTempDir 内部
// 使用 filepath.Rel 可以避免直接 HasPrefix 带来的大小写、路径分隔符以及部分目录名重合的问题
rel, err := filepath.Rel(realTempDir, execDir)
isGoRun := false
if err == nil {
// 如果 rel 不以 ".." 开头,说明 execDir 在 TempDir 内部,即为 go run 模式
if rel != ".." && !strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
isGoRun = true
}
} else {
// fallback: 如果 Rel 失败(例如跨盘符),则退回简单的 HasPrefix 判断(带上分隔符防误判)
cleanTemp := filepath.Clean(realTempDir) + string(os.PathSeparator)
cleanExec := filepath.Clean(execDir) + string(os.PathSeparator)
if strings.HasPrefix(strings.ToLower(cleanExec), strings.ToLower(cleanTemp)) {
isGoRun = true
}
}
if isGoRun {
baseDir = workDir
} else {
baseDir = execDir
}
return baseDir
}