Probably by either using the Windows Script Host Object Model or the Shell Controls and Automation Library. Link resolution can be a dynamic process though and trying to access the Target can produce dialogs, invoke Windows Installer, etc.
From the menu bar click Project then reference. Select microsoft Shell Controls And Automation from the list. If its not there, click browse and select shell32.dll from Windows\System32 folder.
In this example, there is an image at "D:\BG.jpg". The shortcut is at "D:\Shortcut to BG.jpg.lnk".
vb Code:
Option Explicit
Private Sub Form_Load()
Dim oSH32 As Shell, oItem As Shell32.FolderItem, oFldr As Shell32.Folder
Set oSH32 = New Shell
Set oFldr = oSH32.NameSpace("D:\")
Set oItem = oFldr.ParseName("Shortcut to BG.jpg.lnk")
Option Explicit
Private Sub Command1_Click()
Debug.Print GetTarget("C:\Test.Lnk")
End Sub
Function GetTarget(ByVal FileName As String) As String
Dim Obj As Object, Shortcut As Object
Set Obj = CreateObject("WScript.Shell")
Set Shortcut = Obj.CreateShortcut(FileName)
GetTarget = Shortcut.TargetPath
Set Obj = Nothing
Set Shortcut = Nothing
End Function
Last edited by Edgemeal; Jun 4th, 2010 at 12:07 PM.
Re: [RESOLVED] How to get the "Target" from a shortcut file
I think I found one caveat recently.
The library "Microsoft Shell Controls and Automation" did not maintain binary compatibility in all newer versions of Windows for some reason (Microsoft goofed?). So if you use early binding your program created on Windows XP probably won't work on Windows 7 and vice versa. I don't recall where Vista fell in this, but it probably also has the issue.
This is a lot like what you run into when automating Office programs of different versions.
I saw the same sort of problem with ADOX. Initially in Vista there was only an ADOX 6.0 type library, which meant that WinXP programs would fail to run under Vista. In Vista SP2 this was corrected and a typelib for ADOX 2.8 was added (msadox28.tlb) along with adding the ADOX 2.8 interfaces to msadox.dll.
I now try to avoid early binding for any of these things in my programs.
Re: [RESOLVED] How to get the "Target" from a shortcut file
You can also late-bind to Shell32.dll as in:
Code:
Option Explicit
Private Sub Form_Load()
Const ssfDRIVES = 17 'My Computer. Virtual folder containing
'everything on the local computer: storage
'devices, printers, and Control Panel. This
'folder may also contain mapped network drives.
AutoRedraw = True
Show
With CreateObject("Shell.Application").NameSpace(ssfDRIVES). _
ParseName("D:\ZZtestZZ\SomeRandom.lnk")
Print "Shortcut Path: "; .Path
Print "Shortcut Target: "; .GetLink.Path
End With
End Sub
Note the use of ssfDRIVES which avoids the need to parse off the folder name first if you have a full pathname to the shortcut file.
Re: [RESOLVED] How to get the "Target" from a shortcut file
Originally Posted by dilettante
You can also late-bind to Shell32.dll as in:
Code:
Option Explicit
Private Sub Form_Load()
Const ssfDRIVES = 17 'My Computer. Virtual folder containing
'everything on the local computer: storage
'devices, printers, and Control Panel. This
'folder may also contain mapped network drives.
AutoRedraw = True
Show
With CreateObject("Shell.Application").NameSpace(ssfDRIVES). _
ParseName("D:\ZZtestZZ\SomeRandom.lnk")
Print "Shortcut Path: "; .Path
Print "Shortcut Target: "; .GetLink.Path
End With
End Sub
Note the use of ssfDRIVES which avoids the need to parse off the folder name first if you have a full pathname to the shortcut file.
Re: [RESOLVED] How to get the "Target" from a shortcut file
I'll be calling the ''GetTarget2'' about 20 times in a row, there is no references, so the Created Object will be destroyed on ''End Function'', yes/no?
Code:
Function GetTarget2(ByVal FileName As String) As String
With CreateObject("Shell.Application").NameSpace(17).ParseName(FileName)
GetTarget2 = .GetLink.Path
End With
End Function
Re: [RESOLVED] How to get the "Target" from a shortcut file
If you need to fetch several of these you can reduce the overhead by not re-creating the objects repeatedly:
Code:
Option Explicit
Private Const ssfDRIVES = 17 'My Computer. Virtual folder containing
'everything on the local computer: storage
'devices, printers, and Control Panel. This
'folder may also contain mapped network drives.
Private MyComputer As Object
Private Function GetTarget(ByVal LinkPath As String) As String
GetTarget = MyComputer.ParseName(LinkPath).GetLink.Path
End Function
Private Sub Form_Load()
Set MyComputer = CreateObject("Shell.Application").NameSpace(ssfDRIVES)
AutoRedraw = True
Show
Print GetTarget("D:\SomeShortcuts\Notepad.lnk")
Print GetTarget("D:\SomeShortcuts\WMPlayer.lnk")
End Sub
In this case MyComputer will release its reference when the Form unloads. If you had a reason to release it early (done with it but lots more to do in the program) just set it to Nothing.
It would probably be cleaner to bundle all of this in a Class.