Results 1 to 3 of 3

Thread: [VB6] Code Snippet: View shortcut path w/variables unexpanded: IShellLinkDataList

Threaded View

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    7,654

    [VB6] Code Snippet: View shortcut path w/variables unexpanded: IShellLinkDataList

    Shortcuts are actually far more complex than most people realize even after dealing with the IShellLink interface. The really technical bits are hidden behind a whole other interface: IShellLinkDataList.

    Windows shortcuts and shortcuts placed by some programs allow the path to refer to a special location that might vary: for example, the Windows Media Player start menu shortcut on Windows 7 was actually created with a target of %ProgramFiles(x86)%\Windows Media Player\wmplayer.exe. Whether you click it, load its properties page, or call IShellLink's GetPath, the special Program Files reference will be expanded. But what if you want to see that original reference? Here I bring another article from the wonderful Old New Thing blog to VB6. As part of the code, you can also see all the SLDF_ flags associated with a link.

    Requirements
    -Windows XP or higher
    -oleexp 3.51 or newer (released with this code on 9 May 2016; 3.5 will NOT work); oleexp3.tlb must be added under Project-References, but it's an IDE-only requirement- the typelib does not need to be distributed with the compiled EXE.

    The Code
    Code:
    Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    
    Public Sub ShowLinkInfo(sLink As String)
    'sLink must include .lnk suffix (hidden even when 'show extensions' is enabled)
    'e.g. C:\folder\Shortcut to MyProgram.exe.lnk
    
    Dim psdi As IShellLinkDataList
    Dim pLNK As ShellLinkW
    Dim ppf As IPersistFile
    Set pLNK = New ShellLinkW
    Set ppf = pLNK
    ppf.Load sLink, STGM_READ
    Set psdi = pLNK
    Dim dwFlg As SHELL_LINK_DATA_FLAGS
    psdi.GetFlags dwFlg
    Debug.Print "flags=" & Hex$(dwFlg)
    
    If (dwFlg And SLDF_HAS_EXP_SZ) Then
        Debug.Print "has exp_sz"
        Dim tEXP As EXP_SZ_LINK
        Dim ltPtr As Long
        psdi.CopyDataBlock EXP_SZ_LINK_SIG, ltPtr
        If ltPtr Then
            Debug.Print "got non-zero ptr"
            CopyMemory tEXP, ByVal ltPtr, LenB(tEXP)
            
            Debug.Print "struct size=" & tEXP.cbSize & ",sig=" & Hex$(tEXP.dwSignature)
            Debug.Print "str=" & WCHARtoSTR(tEXP.swzTarget)
        Else
            Debug.Print "no ptr to tEXP"
        End If
    Else
        Debug.Print "no flag match"
    End If
    End Sub
    
    Public Function WCHARtoSTR(aCh() As Integer) As String
    Dim i As Long
    Dim sz As String
    For i = LBound(aCh) To UBound(aCh)
        If aCh(i) <> 0 Then
            sz = sz & ChrW(CLng(aCh(i)))
        End If
    Next
    WCHARtoSTR = sz
    End Function
    (Note: I tried copying directly into the struct by passing tEXP or trying ByVal VarPtr(tEXP); but both resulted in the value of the memory pointer being shoved into the .cbSize member.)

    You can set flags and add/delete data blocks as well, look for a far more advanced demo of this interface in the future.
    Last edited by fafalone; May 9th, 2016 at 01:29 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width