How to follow a shortcut in powershell
Asked Answered
Y

3

6

In powershell, you use cd dir to go into the directory dir.

But if dir is a shortcut to a directory, cd dir and cd dir.lnk both give an error, saying that the directory doesn't exist.

So how do I follow that shortcut?

(In Linux cd dir just works. In Windows, I've got no idea)

Yawmeter answered 18/9, 2017 at 9:54 Comment(2)
Windows shortcut is actually a binary file that needs explicit parsing or COM access. NTFS supports symbolic links too (like the Ext fs in Linux), but those are seldom used.Taxeme
See also: #54729010Intonation
P
5

Using the shell com-object, you can get the target path and from there, do what you wish. Get-ShortcutTargetPath

function Get-ShortcutTargetPath($fileName) {
    $sh = New-Object -COM WScript.Shell
    $targetPath = $sh.CreateShortcut($fileName).TargetPath 
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sh) | Out-Null
    return $targetPath
}


$file = 'Path\to\Filename.lnk'
$TargetPath = Get-shortcutTargetPath($file)

if (Test-Path -PathType Leaf $TargetPath) {
    $TargetPath = Split-Path -Path $TargetPath
}

Set-Location $TargetPath
Penn answered 18/9, 2017 at 13:17 Comment(2)
The $TargetPath contains the executable name which cannot be used with Set-Location. Perhaps Set-Location $(Split-Path -Path $TargetPath)Rost
@Rost Indeed. I edited my code to include a Split-Path based on your comment. If the target is a container though, it is important to not perform the Split-Path, otherwise you'll get the parent container of the target container.Penn
S
0

The other answers don't actually work for me, the first does nothing and the second gives me the error "The shortcut pathname must end with .lnk or .url."

However, after digging through MSDN for a while I worked out a solution. I have no idea why I can't find any answers to this on Google, but I even travelled to the untouched second and third pages and tried multiple keywords... I guess the search results are just buried for some reason. But here's how I solved the problem. Using a while loop and the Get-Item command, you can follow a symbolic link to it's true path! Works for directory links, too.

So far the double-cd approach is the most reliable/universal I can find for handling a situation of mixed relative/absolute paths in the filenames and targets, and I tested several scenarios.

function getLinkTarget($fn) {
    $op=$PWD #Save original path
    while($t=(Get-Item $fn).Target) { #Get link target
        cd (Split-Path -Parent $fn) #cd to parent of file/dir
        cd (Split-Path -Parent $t) #cd again to parent of target
        $fn=(Split-Path -Leaf $t) #Set filename to relative target
    }
    $fn=(Join-Path $PWD $fn) #Make path absolute
    cd $op #Change back to original path
    return $fn
}
Schellens answered 17/2, 2023 at 23:59 Comment(0)
A
-1

In Windows 10 cd directory_name or cd dir* if you only want part of the name assuming no other directories start with the same dir*.

enter image description here

Andino answered 14/7, 2019 at 20:18 Comment(1)
That doesn't work. cd : Cannot find path 'src*' because it does not exist.Yawmeter

© 2022 - 2024 — McMap. All rights reserved.