I celebrated too soon.

The code works great if I manually specify the LNK file in code, but it doesn't work with OpenFileRequester() because it just returns the EXE without the command-line parts. Any way around that?
Code: Select all
EnableExplicit
#Version = "1.06"
Structure ShellLinkHeaderStr
HeaderSize.l
LinkCLSID.a[16]
LinkFlags.l
FileAttributes.l
CreationTime.q
AccessTime.q
WriteTime.q
FileSize.l
IconIndex.l
ShowCommand.l
HotKey.w
Reserved1.w
Reserved2.l
Reserved3.l
EndStructure
Enumeration ; LinkFlags
#HasLinkTargetIDList
#HasLinkInfo
#HasName
#HasRelativePath
#HasWorkingDir
#HasArguments
#HasIconLocation
#IsUnicode
#ForceNoLinkInfo
#HasExpString
#RunInSeparateProcess
#Unused1
#HasDarwinID
#RunAsUser
#HasExpIcon
#NoPidAlias
#Unused2
#RunWithShimLayer
#ForceNoLinkTrack
#EnableTargetMetadata
#DisableLinkPathTracking
#DisableKnownFolderTracking
#DisableKnownFolderAlias
#AllowLinkToLink
#UnaliasOnSave
#PreferEnvironmentPath
#KeepLocalIDListForUNCTarget
EndEnumeration
Structure LinkInfoStr
LinkInfoSize.l
LinkInfoHeaderSize.l
LinkInfoFlags.l
VolumeIDOffset.l
LocalBasePathOffset.l
CommonNetworkRelativeLinkOffset.l
CommonPathSuffixOffset.l
LocalBasePathOffsetUnicode.l
CommonPathSuffixOffsetUnicode.l
EndStructure
Structure LocalVolumeTableStr
Length.l
TypeOfVolume.l
VolumeSerialNumber.l
OffsetOfVolumeName.l
EndStructure
Procedure.s GetLinkTarget(FileName$)
Protected *Header, Pos, Target$, *Buffer, UniCode, PeekSFlag
Protected *ShellLinkHeader.ShellLinkHeaderStr
Protected *LinkInfo.LinkInfoStr
; Filename$ = "C:\PB\PureBasic_x64-.lnk"
If ReadFile(0, Filename$)
Define ByteLengthW.w, ByteLengthL.l, CharLength.w
ReadData(0, @ByteLengthL, 4)
FileSeek(0, 0)
*Header = AllocateMemory(ByteLengthL)
If ReadData(0, *Header, ByteLengthL) = ByteLengthL
*ShellLinkHeader.ShellLinkHeaderStr = *Header
If *ShellLinkHeader\LinkFlags & (1 << #HasLinkTargetIDList)
ReadData(0, @ByteLengthW, 2)
; skip the LinkTargetIDList for now
FileSeek(0, Loc(0) + ByteLengthW)
EndIf
If *ShellLinkHeader\LinkFlags & (1 << #IsUnicode)
UniCode = #True
PeekSFlag = #PB_Unicode
Else
UniCode = #False
PeekSFlag = #PB_Ascii
EndIf
Pos = Loc(0)
If *ShellLinkHeader\LinkFlags & (1 << #HasLinkInfo)
ReadData(0, @BytelengthL, 4)
If ByteLengthL > 0
FileSeek(0, Pos)
*Buffer = AllocateMemory(ByteLengthL)
If ReadData(0, *Buffer, ByteLengthL) = ByteLengthL
*LinkInfo.LinkInfoStr = *Buffer
Target$ = PeekS(*Buffer + *LinkInfo\LocalBasePathOffset, - 1, #PB_Ascii)
Target$ + PeekS(*Buffer + *LinkInfo\CommonPathSuffixOffset, - 1, #PB_Ascii)
Else
Debug "Error: Target"
EndIf
FreeMemory(*Buffer)
EndIf
Else
Target$ = "Error: " + Filename$ + " has no LinkInfo"
EndIf
; If *ShellLinkHeader\LinkFlags & (1 << #HasName)
; ReadData(0, @ByteLengthW, 2)
; *Buffer = AllocateMemory(ByteLengthW)
; If ReadData(0, *Buffer, ByteLengthW) = ByteLengthW
; Debug ("Description: " + PeekS(*Buffer))
; Else
; End 3
; EndIf
; FreeMemory(*Buffer)
; EndIf
If *ShellLinkHeader\LinkFlags & (1 << #HasRelativePath)
ReadData(0, @CharLength, 2)
If UniCode
ByteLengthW = CharLength * 2
Else
ByteLengthW = CharLength
EndIf
*Buffer = AllocateMemory(ByteLengthW)
If ReadData(0, *Buffer, ByteLengthW) = ByteLengthW
; Debug ("RelativePath: " + PeekS(*Buffer, CharLength, PeekSFlag))
Else
Debug "Error: RelativePath"
EndIf
FreeMemory(*Buffer)
EndIf
If *ShellLinkHeader\LinkFlags & (1 << #HasWorkingDir)
ReadData(0, @CharLength, 2)
If UniCode
ByteLengthW = CharLength * 2
Else
ByteLengthW = CharLength
EndIf
*Buffer = AllocateMemory(ByteLengthW)
If ReadData(0, *Buffer, ByteLengthW) = ByteLengthW
; Debug ("WorkingDirectory: " + PeekS(*Buffer, CharLength, PeekSFlag))
Else
Debug "Error: WorkingDirectory"
EndIf
FreeMemory(*Buffer)
EndIf
If *ShellLinkHeader\LinkFlags & (1 << #HasArguments)
ReadData(0, @CharLength, 2)
If UniCode
ByteLengthW = CharLength * 2
Else
ByteLengthW = CharLength
EndIf
*Buffer = AllocateMemory(ByteLengthW)
If ReadData(0, *Buffer, ByteLengthW) = ByteLengthW
; Debug ("CommandlineArguments: " + PeekS(*Buffer, CharLength, PeekSFlag))
Debug Target$ + " " + PeekS(*Buffer, CharLength, PeekSFlag)
Else
Debug "Error: CommandlineArguments"
EndIf
FreeMemory(*Buffer)
EndIf
; there is more stuff, but not interresting for now.
Else
End 1
EndIf
FreeMemory(*Header)
CloseFile(0)
Else
Debug ("Was not able to open " + Filename$)
EndIf
EndProcedure
;Debug GetLinkTarget("d:\shortcut.lnk") ; Works great directly from code.
Debug GetLinkTarget(OpenFileRequester("Select LNK file","d:\","",0)) ; Doesn't when I select the LNK file.