FileGetShortcut: Wrong 'OutTarget' for 64 bit program files

Report problems with documented functionality
zotune
Posts: 72
Joined: 17 Nov 2014, 17:57

FileGetShortcut: Wrong 'OutTarget' for 64 bit program files

Post by zotune » 30 Apr 2018, 10:24

Code: Select all

;requires a 64 bit windows system

;1 - create .lnk shortcut 'C:\test.lnk'
;2 - set target to an executable in 'C:\Program Files', for example: 'C:\Program Files\test.exe'

;3 - run this script:
FileGetShortcut, c:\test.lnk, OutTarget, OutDir
msgbox % OutTarget ;wrong 'C:\Program Files (x86)\test.exe' ;results to x86 Program Files for some reason???
msgbox % OutDir ;correct 'C:\Program Files\'
User avatar
TheDewd
Posts: 1092
Joined: 19 Dec 2013, 11:16
Location: USA

Re: FileGetShortcut: Wrong 'OutTarget' for 64 bit program files

Post by TheDewd » 01 May 2018, 09:43

It sounds like you're executing the code using the 32-bit version of AutoHotkey.

If you run the code using the 64-bit version (AutoHotkeyU64.exe), the path is reported correctly.

I wrote a function to help you with this issue. See below:

Code: Select all

MsgBox, % ShortcutGetTarget("C:\test.lnk")

ShortcutGetTarget(ShortcutPath) {
	FileGetShortcut, % ShortcutPath, OT, OD
	RegExMatch(OD, "\\(.*?)\\", ODM)
	RegExMatch(OT, "\\(.*?)\\", OTM)
	return StrReplace(OT, OTM1, ODM1,, 1)
}
Image Bulldozer - Sokoban inspired game from 1994 recreated in AutoHotkey.
User avatar
jeeswg
Posts: 5132
Joined: 19 Dec 2016, 01:58
Location: UK

Re: FileGetShortcut: Wrong 'OutTarget' for 64 bit program files

Post by jeeswg » 01 May 2018, 10:52

I tried two approaches which unfortunately still got the wrong (32-bit) target, but I share them here to avoid people duplicating the effort. (I tried Wow64DisableWow64FsRedirection and using a ShellLinkObject object.)

Code: Select all

;FolderItem object (Windows)
;https://msdn.microsoft.com/en-us/library/windows/desktop/bb787810(v=vs.85).aspx
;ShellLinkObject object (Windows)
;https://msdn.microsoft.com/en-us/library/windows/desktop/bb774004(v=vs.85).aspx

q:: ;get path of lnk file
vPath := A_Desktop "\MyLink.lnk"
if A_Is64bitOS
	DllCall("kernel32\Wow64DisableWow64FsRedirection", UIntP,0)
FileGetShortcut, % vPath, vTarget
MsgBox, % vTarget

SplitPath, vPath, vName, vDir
oShell := ComObjCreate("Shell.Application")
oItem := oShell.NameSpace(vDir).ParseName(vName)
;MsgBox, % oItem.Name
oLink := oItem.GetLink
MsgBox, % oLink.Path
oShell := oItem := oLink := ""
return
malcev
Posts: 95
Joined: 12 Aug 2014, 12:37

Re: FileGetShortcut: Wrong 'OutTarget' for 64 bit program files

Post by malcev » 01 May 2018, 16:10

It can be done with wmi:

Code: Select all

lnk := "C:\My Link.lnk"
msgbox % ComObjGet("winmgmts:").ExecQuery("Select * from Win32_ShortcutFile where Name=""" StrReplace(lnk, "\", "\\") """").ItemIndex(0).Target
User avatar
jeeswg
Posts: 5132
Joined: 19 Dec 2016, 01:58
Location: UK

Re: FileGetShortcut: Wrong 'OutTarget' for 64 bit program files

Post by jeeswg » 01 May 2018, 16:47

- Thanks so much malcev, great find. It gives the correct path even in AHK 32-bit.
- If anybody else has any other approaches for getting link targets, that either do or don't do the file redirection, it would be interesting to see them. Thanks.
lexikos
Posts: 6175
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: FileGetShortcut: Wrong 'OutTarget' for 64 bit program files

Post by lexikos » 03 May 2018, 03:22

FileGetShortcut gives you the exact path returned by IShellLink::GetPath.

Adding SLGP_RAWPATH (which "may include environment variables that need to be expanded") doesn't help, presumably because the shell does automatic translation for "Program Files", not just "%ProgramFiles%".

The path given by GetPath is correct, from a certain perspective: it accurately reflects the path that will be executed if the .lnk file is executed by the same type of process as the one calling GetPath. For example, if FileGetShortcut C:\test.lnk returns "C:\Program Files (x86)\test.exe", then Run C:\test.lnk will either execute that file or (if the file doesn't exist) fail.

The 32-bit version of cmd.exe (C:\Windows\SysWow64\cmd.exe) also behaves this way.

I would guess that WMI doesn't do the work directly, but in an external 64-bit worker process or service.
zotune
Posts: 72
Joined: 17 Nov 2014, 17:57

Re: FileGetShortcut: Wrong 'OutTarget' for 64 bit program files

Post by zotune » 05 May 2018, 05:03

Thanks for the workaround @malcev.

And thanks for all the hard work you do @lexikos
Post Reply

Return to “Bug Reports”