Reading a shortcut

by Jon Ripley, January 2008

If you want to read the name of the file or directory pointed to by a short cut (link) file you can use the routine listed below. FNShell_GetShortcut takes a full path to a short cut (link) file and returns a path to the linked file:

        DEF FNShell_GetShortcut(LinkFile$)
        LOCAL ole32%, clsid%, iidsl%, iidpf%, wsz%, psl%, ppf%, psl{}, ppf{}, path%
 
        DIM clsid% LOCAL 15, iidsl% LOCAL 15, iidpf% LOCAL 15, path% LOCAL 255
        DIM wsz% LOCAL 2*LEN(LinkFile$)+1
        DIM psl{QueryInterface%, AddRef%, Release%, GetPath%, GetIDList%, SetIDList%, \
        \       GetDescription%, SetDescription%, GetWorkingDirectory%, \
        \       SetWorkingDirectory%, GetArguments%, SetArguments%, \
        \       GetHotkey%, SetHotkey%, GetShowCmd%, SetShowCmd%, GetIconLocation%, \
        \       SetIconLocation%, SetRelativePath%, Resolve%, SetPath%}
        DIM ppf{QueryInterface%, AddRef%, Release%, GetClassID%, IsDirty%, \
        \       Load%, Save%, SaveCompleted%, GetCurFile%}
 
        SYS "LoadLibrary", "OLE32.DLL" TO ole32%
        SYS "GetProcAddress", ole32%, "CoInitialize" TO `CoInitialize`
        SYS "GetProcAddress", ole32%, "CoUninitialize" TO `CoUninitialize`
        SYS "GetProcAddress", ole32%, "CoCreateInstance" TO `CoCreateInstance`
 
        SYS `CoInitialize`, 0
 
        clsid%!0  = &00021401 : REM CLSID_ShellLink
        clsid%!4  = &00000000
        clsid%!8  = &000000C0
        clsid%!12 = &46000000
 
        iidsl%!0  = &000214EE : REM IID_IShellLink
        iidsl%!4  = &00000000
        iidsl%!8  = &000000C0
        iidsl%!12 = &46000000
 
        iidpf%!0  = &0000010B : REM IID_IPersistFile
        iidpf%!4  = &00000000
        iidpf%!8  = &000000C0
        iidpf%!12 = &46000000
 
        REM Get a pointer to the IShellLink interface:
        _CLSCTX_INPROC_SERVER = 1
        SYS `CoCreateInstance`, clsid%, 0, _CLSCTX_INPROC_SERVER, iidsl%, ^psl%
        IF psl% = 0 ERROR 100, "Cannot create IShellLink interface"
        !(^psl{}+4) = !psl%
 
        REM Query IShellLink for the IPersistFile interface:
        SYS psl.QueryInterface%, psl%, iidpf%, ^ppf%
        IF ppf% = 0 ERROR 100, "Cannot create IPersistFile interface"
        !(^ppf{}+4) = !ppf%
 
        REM Convert the path string to Unicode:
        SYS "MultiByteToWideChar", 0, 0, LinkFile$, -1, wsz%, LEN(LinkFile$)+1
 
        REM Load the link by calling IPersistFile::Load:
        SYS ppf.Load%, ppf%, wsz%, 0
 
        REM Get the target object:
        SYS psl.GetPath%, psl%, path%, 256, 0, 0
 
        REM Tidy up:
        SYS ppf.Release%, ppf%
        SYS psl.Release%, psl%
        SYS `CoUninitialize`
        =$$path%


For information about how to create a short cut see the article on creating a shortcut.