pathutil_windows.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package pathutil
  2. import (
  3. "errors"
  4. "io/fs"
  5. "os"
  6. "path/filepath"
  7. "strings"
  8. "golang.org/x/sys/windows"
  9. )
  10. // UserHomeDir returns the home directory of the current user.
  11. func UserHomeDir() string {
  12. return KnownFolder(windows.FOLDERID_Profile, []string{"USERPROFILE"}, nil)
  13. }
  14. // Exists returns true if the specified path exists.
  15. func Exists(path string) bool {
  16. fi, err := os.Lstat(path)
  17. if fi != nil && fi.Mode()&os.ModeSymlink != 0 {
  18. _, err = filepath.EvalSymlinks(path)
  19. }
  20. return err == nil || errors.Is(err, fs.ErrExist)
  21. }
  22. // ExpandHome substitutes `%USERPROFILE%` at the start of the specified `path`.
  23. func ExpandHome(path string) string {
  24. home := UserHomeDir()
  25. if path == "" || home == "" {
  26. return path
  27. }
  28. if strings.HasPrefix(path, `%USERPROFILE%`) {
  29. return filepath.Join(home, path[13:])
  30. }
  31. return path
  32. }
  33. // KnownFolder returns the location of the folder with the specified ID.
  34. // If that fails, the folder location is determined by reading the provided
  35. // environment variables (the first non-empty read value is returned).
  36. // If that fails as well, the first non-empty fallback is returned.
  37. // If all of the above fails, the function returns an empty string.
  38. func KnownFolder(id *windows.KNOWNFOLDERID, envVars []string, fallbacks []string) string {
  39. if id != nil {
  40. flags := []uint32{windows.KF_FLAG_DEFAULT, windows.KF_FLAG_DEFAULT_PATH}
  41. for _, flag := range flags {
  42. p, _ := windows.KnownFolderPath(id, flag|windows.KF_FLAG_DONT_VERIFY)
  43. if p != "" {
  44. return p
  45. }
  46. }
  47. }
  48. for _, envVar := range envVars {
  49. p := os.Getenv(envVar)
  50. if p != "" {
  51. return p
  52. }
  53. }
  54. for _, fallback := range fallbacks {
  55. if fallback != "" {
  56. return fallback
  57. }
  58. }
  59. return ""
  60. }