• string represents a shortcut link? (VB/VBA any)

    Home » Forums » AskWoody support » Productivity software by function » Visual Basic for Applications » string represents a shortcut link? (VB/VBA any)

    Author
    Topic
    #432253

    Is there a better way to test if a string represents a shortcut link?

    Sub TESTblnShortCut()
        MsgBox blnShortCut("C:Blotter200604041")
        MsgBox blnShortCut("C:Blotter200604041", ".lnk")
        MsgBox blnShortCut("C:Blotter200604041", ".bat")
    End Sub
    
    Public Function blnShortCut(ByVal strfile As String, Optional strExtent) As Boolean
        On Error GoTo Failed
        If FileLen(strfile) > 0 Then
        Else
        End If
        Exit Function
    Failed:
        Dim strExt As String
        If IsMissing(strExtent) Then
            strExt = ".lnk"
        Else
            strExt = strExtent
        End If
        strfile = strfile & strExt
        blnShortCut = blnShortCut2(strfile)
    End Function
    Public Function blnShortCut2(ByVal strfile As String) As Boolean
        On Error GoTo Failed
        If FileLen(strfile) > 0 Then
        Else
        End If
        blnShortCut2 = True
        Exit Function
    Failed:
    End Function
    Viewing 2 reply threads
    Author
    Replies
    • #1013638

      What are you doing? I can’t follow it.

      What is FileLen?

      • #1013772

        >What are you doing? I can’t follow it.
        Basically, if a file is a shortcut link, the extent “lnk” does not appear when I FSO or similar to retrieve file names.
        If I test for the existence (FileLen) of the filename as given (without the extent) it fails, so generates an error.
        If I append a best-guess at an extent and test again and this time the FileLen does NOT generate an error, it’s probably a shortcut; that is, appending the “lnk” extent indicated that there is such a file, so the original file name without the “lnk” was a shortcut link.

        FileLen returns the length of the file in bytes, as in

        Sub test()
            MsgBox FileLen(MacroContainer.FullName)
        End Sub
        
    • #1013823

      If you feed your function “1.lnk”, it returns False, which isn’t what you want, correct?

      Does the following do what you want?

      Function blnShortCut(strFile As String) As Boolean
      
          If Right$(strFile, 4) = ".lnk" Then
              If FileLen(strFile) > 0 Then
                  blnShortCut = True
              End If
           Else
              If FileLen(strFile & ".lnk") > 0 Then
                  blnShortCut = True
              End If
          End If
      
      End Function
      • #1013841

        Thanks for your patience.

        > If you feed your function “1.lnk”, it returns False, which isn’t what you want, correct?
        You are correct. However If I am given a filename with an extension of “lnk”, I’m prepared to accept it as a shortcut link. (Further analysis will reveal whether or not it really is a link).
        My problem is determining if a file other than one with an explicit extension of “lnk” is a shortcut link.
        Try running this code on a folder that contains a mixture of shortcuts and regular files

        Public Sub GetFolderItems()
        ' needs a reference to microsoft shells and controls automation
            On Error Resume Next
            Dim FI As Shell32.FolderItem, i As Long
            With New Shell
                With .NameSpace("c:Blotter20060404")
                    For Each FI In .Items
                        If Not (FI Is Nothing) Then
                            If FI.IsFolder Then
                                'evaluate this namespece
                            Else
                                'add to dictionary
                                Debug.Print FI.Name
                            End If
                        End If
                    Next
                End With
            End With
            Set FI = Nothing
        End Sub

        On my Office 2000 system it returns the shortcut link files without the “lnk” extension. Us mortals aren’t told about the extension on shortcut link files.
        I was/am looking for a way to determine if a file passed to me by the system routines is a link file, or is just a regular file.
        I may have missed something in reading the help files and various forums and newsgroups, but it seems to me that we are not given that “lnk” extension, and must play a bit of a guessing game to see if the file really is a shortcut. (“Does it have an extension, if so, is it “lnk”, if not, if i place a “lnk” there does the file exist? …)

        • #1013883

          Your latest post is consistent with my assumptions about what you were doing, so I think the code in my previous post will do what you want, but I may be missing something. (You could shorten it a little if you’ve already determined the target file doesn’t end in .lnk before you invoke the blnShortCut function.)

        • #1013944

          On my system (Office 2K, running on WIN XP) the FileSystemObject methods correctly listed files with the .lnk extension. Not sure why your system did not reflect this. Anyway if interested see attached text file, exported VBA code module. The ListFiles sub lists all files in specified folder (using FSO) & related info. If file has “.lnk” extension the FSO File.Type property returns “Shortcut” (based solely on file extension as registered in Windows Registry). However you can rename a file with .lnk extension whether or not a valid shortcut (you can tell if valid or not by right-clicking file & opening “Properties” dialog – the Target Type will read, “This is not a valid shortcut.”) You could use ShellExecute function to open Properties dialog programatically, but that wouldn’t be too useful… Tried using WSH methods to verify if valid shortcut, but that did not work either – there is no “OpenShortcut” method, only the CreateShortcut method (which can be used to open existing shortcut). This proved not very useful, since you can create a new shortcut w/o target path, etc, specified – see IsShortcutWSH function as an exercise in futility. Finally decided most reliable method is that used in IsShortcut function – if valid file spec with .lnk extension, read the first 20 bytes of file into a Byte array. A valid shortcut file will always have the letter “L” (or Hex 4C) (4 bytes) followed by a 16-byte GUID in the first 20 bytes of file header (you can test this by running ListFiles with a folder that has valid shortcut files – you should see the same 20 byte values listed). The bogus “.lnk” file will return False when run function. If running repeatedly you’d probably want to populate the bTest byte array only once. See attached text file for details. This worked correctly on two different Office 2K/WIN XP systems. You may be able to adapt this for your purposes.

          HTH

          • #1013967

            Mark, thanks for the extensive and exhaustive research.

            >there is no “OpenShortcut” method, only the CreateShortcut method
            I have recollections of seeing something, somewhere, along the lines of “there is no “OpenShortcut” method, only the CreateShortcut method … but the Create method can be used to create an object that can be tested.”. I must go back over my notes and di that out. (later) i think this is it

                For lng = LBound(strFiles) To UBound(strFiles)
                    Dim strTarget As String
                    strTarget = Utils.strShortCut(strFiles(lng))
                    If Len(strTarget) > 0 Then ' it is a shortcut link
                        Dim strMsg As String
                        strMsg = "Shortcut file " & strFiles(lng)
                        Application.StatusBar = Trim(Str(lng)) & "/" & Trim(Str(UBound(strFiles))) & " " & strFiles(lng)
                        With CreateObject("WScript.Shell").CreateShortcut(strTarget)
                            Dim strTargetPath As String
                            strTargetPath = .targetpath
                            If UW.blnfileexists(strTargetPath) Then
                                strMsg = strMsg & " found "
                            Else
                                strMsg = strMsg & " NOT found "
                                Call UW.KillFile(strTarget)
                            End If
                            Call logfile((strEnv) & strcApplication & ".LOG", strMsg)
                        End With
                    Else
                    End If
                Next lng
            

            The “With CreateObject(“WScript.Shell”).CreateShortcut(strTarget)” creates an object but doesn’t .Save it (yet), and the object, which just so happens to refer to an existing file, can then be interrogated.
            I’m not sure of this, but it seems to work.

            >A valid shortcut file will always have the letter “L” (or Hex 4C) (4 bytes) followed by a 16-byte GUID in the first 20 bytes of file header
            This is of very high value for two reasons:
            (1) I can add it to my set of constraints for testing file types by content, such as WP5.1 DOS files etc
            (2) The current application is an Archiver, so grabbing 20 bytes of an existing file is no big deal, given that we are a background, low-priority task anyway, and it is wise to take every step possible to identify correctly each file.

            Again, Mark, many thanks.

    • #1014628

      Chris
      I suspect that you could adapt the code in this post from Hans.

      • #1014725

        I suspect you are right!
        I hate On Error with a passion; it always seems to me to be a catch-all for unplanned events.
        OTOH sending a file, any file, to Hans’s code and returning the error should tell me whether or not it was a shortcut, and I much prefer that than relying on a vaporous extent.

        Thanks Don!

    Viewing 2 reply threads
    Reply To: string represents a shortcut link? (VB/VBA any)

    You can use BBCodes to format your content.
    Your account can't use all available BBCodes, they will be stripped before saving.

    Your information: