mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-11-09 20:44:03 -08:00
feat(windows): parse app exec links
This commit is contained in:
parent
9568289cc8
commit
f6a8c8dc87
|
@ -12,7 +12,6 @@ import (
|
|||
"net/http"
|
||||
"net/http/httputil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
|
@ -609,12 +608,14 @@ func (env *Shell) CommandPath(command string) string {
|
|||
env.Debug(path)
|
||||
return path
|
||||
}
|
||||
path, err := exec.LookPath(command)
|
||||
|
||||
path, err := env.LookPath(command)
|
||||
if err == nil {
|
||||
env.cmdCache.set(command, path)
|
||||
env.Debug(path)
|
||||
return path
|
||||
}
|
||||
|
||||
env.Error(err)
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
package platform
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -156,8 +156,8 @@ func (env *Shell) ConvertToLinuxPath(path string) string {
|
|||
return path
|
||||
}
|
||||
|
||||
func (env *Shell) LookWinAppPath(_ string) (string, error) {
|
||||
return "", errors.New("not relevant")
|
||||
func (env *Shell) LookPath(command string) (string, error) {
|
||||
return exec.LookPath(command)
|
||||
}
|
||||
|
||||
func (env *Shell) DirIsWritable(path string) bool {
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
@ -249,3 +251,17 @@ func (env *Shell) Connection(connectionType ConnectionType) (*Connection, error)
|
|||
env.Error(fmt.Errorf("Network type '%s' not found", connectionType))
|
||||
return nil, &NotImplemented{}
|
||||
}
|
||||
|
||||
func (env *Shell) LookPath(command string) (string, error) {
|
||||
winAppPath := filepath.Join(env.Getenv("LOCALAPPDATA"), `\Microsoft\WindowsApps\`, command)
|
||||
if !strings.HasSuffix(winAppPath, ".exe") {
|
||||
winAppPath += ".exe"
|
||||
}
|
||||
|
||||
path, err := exec.LookPath(command)
|
||||
if err == nil && path != winAppPath {
|
||||
return path, nil
|
||||
}
|
||||
|
||||
return readWinAppLink(winAppPath)
|
||||
}
|
||||
|
|
|
@ -350,3 +350,49 @@ func (env *Shell) Memory() (*Memory, error) {
|
|||
PhysicalPercentUsed: float64(memStat.MemoryLoad),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// openSymlink calls CreateFile Windows API with FILE_FLAG_OPEN_REPARSE_POINT
|
||||
// parameter, so that Windows does not follow symlink, if path is a symlink.
|
||||
// openSymlink returns opened file handle.
|
||||
func openSymlink(path string) (syscall.Handle, error) {
|
||||
p, err := syscall.UTF16PtrFromString(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
attrs := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS)
|
||||
// Use FILE_FLAG_OPEN_REPARSE_POINT, otherwise CreateFile will follow symlink.
|
||||
// See https://docs.microsoft.com/en-us/windows/desktop/FileIO/symbolic-link-effects-on-file-systems-functions#createfile-and-createfiletransacted
|
||||
attrs |= syscall.FILE_FLAG_OPEN_REPARSE_POINT
|
||||
h, err := syscall.CreateFile(p, 0, 0, nil, syscall.OPEN_EXISTING, attrs, 0)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func readWinAppLink(path string) (string, error) {
|
||||
h, err := openSymlink(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
defer syscall.CloseHandle(h) //nolint: errcheck
|
||||
|
||||
rdbbuf := make([]byte, syscall.MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
|
||||
var bytesReturned uint32
|
||||
err = syscall.DeviceIoControl(h, syscall.FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
rdb := (*REPARSE_DATA_BUFFER)(unsafe.Pointer(&rdbbuf[0]))
|
||||
rb := (*GenericDataBuffer)(unsafe.Pointer(&rdb.DUMMYUNIONNAME))
|
||||
appExecLink := (*AppExecLinkReparseBuffer)(unsafe.Pointer(&rb.DataBuffer))
|
||||
if appExecLink.Version != 3 {
|
||||
return "", errors.New("unknown AppExecLink version")
|
||||
}
|
||||
|
||||
return appExecLink.Path()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue