Zurück zur Homepage

Link Dateien parsen

Eine Verknüpfung als Link-Datei zu erstellen, ist relativ leicht. Die .dll mso97.dll (Office 2000 mso9.dll) enthält die Funktion  #315, die so etwas macht. Das Ausführen von .lnk - Dateien funzt gut mittels ShellExecute.
Aber das Auslesen der Informationen in dieser Datei mittels VB(A) bereitet ohne C- Programme oder dll's Probleme, bzw. funktioniert nicht. Da aber jede Datei eine bestimmte Struktur hat, kann man versuchen, diese zu entschlüsseln und die Daten direkt auslesen. Wotsit.com ist eine gute Anlaufstelle für Dateiformate und dort findet sich auch eine Beschreibung. Leider kann MS diese Struktur jederzeit ändern, deshalb auch eine GUID in der Link-Datei, an der das Betriebssystem die Version erkennt. So passt auch zumindestens unter Win 98, XP und Win 2000 nicht alles zu dieser Beschreibung. Ich habe meinen Code aber den geänderten Gegebenheiten angepasst und es läuft relativ gut. Wenn Links von Programmen angelegt werden, kann es schon mal vorkommen, dass nicht alle Infos zur Verfügung stehen. Ein Doppelklick auf den Link wirkt da manchmal wahre Wunder.
Ansonsten einfach mal testen!

Beispieldatei (linken.zip 33 KB)

'########################################################
'# In ein Modul
'########################################################

Option Explicit


Sub test()
Dim Linkname As String
'Pfad anpassen
Linkname = "C:\Dokumente und Einstellungen\" _
    & "schwimmer\Desktop\Analysis.pdf.lnk"
LinkInfos Linkname
End Sub


Public Sub LinkInfos(Linkname As String)

Dim Linkklasse As New clsLink
Dim Itemlist, i As Long
'Blattname anpassen
On Error Resume Next
Worksheets("LinkinfosListe").Cells.Clear
If Linkname = "" Then Exit Sub
With Linkklasse
    .Linkpath = Linkname
    Eintragen "Archive = " & .Archive, 2, "LinkinfosListe"
    Eintragen "Kompressed = " & .Kompressed
    Eintragen "Temporary = " & .Temporary
    Eintragen "Directory = " & .Directory
    Eintragen "System = " & .System
    Eintragen "Hidden = " & .Hidden
    Eintragen "ReadOnly = " & .ReadOnly
    Eintragen "GUID = " & .GUID
    Eintragen "Filelength = " & .Filelength
    Eintragen "IconNumber = " & .IconNumber
    Eintragen "IconPath = " & .IconPath
    Eintragen "CreationTime = " & .CreationTime
    Eintragen "LastAccessTime = " & .LastAccessTime
    Eintragen "LastModifyTime = " & .LastModifyTime
    Eintragen "VolumeArt = " & .VolumeArt
    Eintragen "VolumeSerial = " & .VolumeSerial
    Eintragen "LocalVolumeName = " & .LocalVolumeName
    Eintragen "LocalPath = " & .LocalPath
    Eintragen "FinalPath = " & .FinalPath
    Eintragen "NetworkVolumeName = " & .NetworkVolumeName
    Eintragen "ShareName = " & .ShareName
    Eintragen "RelativePath = " & .RelativePath
    Eintragen "ShowModus = " & .ShowModus
    Eintragen "Workdirectory = " & .Workdirectory
    Eintragen "Commandline Arguments = " & .CommandlineArgs
    Eintragen "Description = " & .Description
    Itemlist = .Itemlist
    For i = 1 To UBound(Itemlist)
        Eintragen "ITEM " & i & " = " & Itemlist(i)
    Next
End With
End Sub


Private Sub Eintragen(myWert As String, _
    Optional Startrow As Long, _
    Optional Blattname As String)

'Werte in Blatt eintragen
Static zeile As Long, Blatt As String
If Blattname <> "" Then Blatt = Blattname
If Startrow <> 0 Then zeile = Startrow
With Worksheets(Blatt)
    .Cells(zeile, 1) = myWert
End With
zeile = zeile + 1
End Sub

 

'########################################################
'# In eine Klasse mit Namen clsLink
'########################################################

Option Explicit
Private Declare Function StringFromGUID2 Lib "ole32" _
    (ByRef rguid As GUID, _
     ByVal lpsz As Long, _
     ByVal cchMax As Long) As Long
Private Declare Function FileTimeToSystemTime Lib "kernel32" _
    (lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long
Private Declare Function FileTimeToLocalFileTime Lib "kernel32" _
    (lpFileTime As FILETIME, lpLocalFileTime As FILETIME) _
    As Long

Private Type GUID

    f1          As Long
    f2          As Integer
    f3          As Integer
    f4(0 To 7)  As Byte

End Type

Private Type FILETIME

    dwLowDateTime As Long
    dwHighDateTime As Long

End Type

Private Type SYSTEMTIME

    wYear As Integer
    wMonth As Integer
    wDayOfWeek As Integer
    wDay As Integer
    wHour As Integer
    wMinute As Integer
    wSecond As Integer
    wMilliseconds As Integer

End Type

Private Type DoubleLong

    a As Long
    b As Long

End Type

Private Type SingleCur

    a As Currency
End Type

Private iLinkpath As String
Private iFinalPath As String
Private iDescription As String
Private iGUID As String
Private iCommandlineArgs As String
Private iWorkdirectory As String
Private iIconPath As String
Private iIconNumber As String
Private iLocalPath As String
Private iNetworkVolumeName As String
Private iShareName As String
Private iCreationTime As String
Private iLastAccessTime As String
Private iLastModifyTime As String
Private iRelativePath As String
Private iEncrypted As Boolean
Private iReadOnly As Boolean
Private iHidden As Boolean
Private iSystem As Boolean
Private iDirectory As Boolean
Private iArchive As Boolean
Private iTemp As Boolean
Private iKomprimiert As Boolean
Private iFilelänge As Long
Private iShow As String
Private iItem() As String
Private iVolumeart As String
Private iVolumeSerial As Currency
Private iLocalVolumeName As String

Private Sub ParseLnk()

Dim ff As Long, länge As Long, intLänge As Integer
Dim BOL As Long, ArrBuff() As Byte, BuffLong As Long
Dim MyGuid As GUID, BuffStr As String, BuffByte As String * 1
Dim zeiger As Long, i As Long, k As Long
Dim IDList As Boolean, LocationList As Boolean
Dim Beschreibung As Boolean, RelPfad As Boolean
Dim WorkDir As Boolean, CommandlineArgs As Boolean
Dim UserdefIcon As Boolean
Dim offsetVol As Long, VolumeFlag As Long
Dim VolLänge As Long, OffsetLocalPath As Long
Dim OffsetNetzwerk As Long, OffsetFinalPath As Long
Dim myFileTime As FILETIME
If iLinkpath = "" Then Close: Zurücksetzen: Exit Sub
If Dir(iLinkpath) = "" Then Close: Zurücksetzen: Exit Sub
ff = FreeFile
zeiger = 0
Open iLinkpath For Binary As ff
    Get ff, , BuffLong
    'Magic L
    If BuffLong <> &H4C Then Close: Zurücksetzen: Exit Sub
    zeiger = zeiger + 4
    'GUID
    Get ff, , MyGuid
    iGUID = String(255, 0)
    länge = StringFromGUID2(MyGuid, StrPtr(iGUID), 255)
    If länge Then iGUID = Left$(iGUID, länge - 1)
    zeiger = zeiger + Len(MyGuid)
    'Flags
    Get ff, , BuffLong
    If BuffLong And 2 ^ 0 Then IDList = True
    If BuffLong And 2 ^ 1 Then LocationList = True
    If BuffLong And 2 ^ 2 Then Beschreibung = True
    If BuffLong And 2 ^ 3 Then RelPfad = True
    If BuffLong And 2 ^ 4 Then WorkDir = True
    If BuffLong And 2 ^ 5 Then CommandlineArgs = True
    If BuffLong And 2 ^ 6 Then UserdefIcon = True
    zeiger = zeiger + 4
    'File Attribute Ziel
    Get ff, , BuffLong
    If BuffLong And 2 ^ 0 Then iReadOnly = True
    If BuffLong And 2 ^ 1 Then iHidden = True
    If BuffLong And 2 ^ 2 Then iSystem = True
    If BuffLong And 2 ^ 4 Then iDirectory = True
    If BuffLong And 2 ^ 5 Then iArchive = True
    If BuffLong And 2 ^ 6 Then iEncrypted = True
    If BuffLong And 2 ^ 8 Then iTemp = True
    If BuffLong And 2 ^ 11 Then iKomprimiert = True
    zeiger = zeiger + 4
    'File Attribute Zeit
    Get ff, , myFileTime
    iCreationTime = myLocalTimeToDateString(myFileTime)
    Get ff, , myFileTime
    iLastModifyTime = myLocalTimeToDateString(myFileTime)
    Get ff, , myFileTime
    iLastAccessTime = myLocalTimeToDateString(myFileTime)
    zeiger = zeiger + 24
    'Filelänge
    Get ff, , iFilelänge
    zeiger = zeiger + 4
    'Iconnummer
    Get ff, , BuffLong
    iIconNumber = BuffLong
    zeiger = zeiger + 4
    'Show
    Get ff, , BuffLong
    If BuffLong = 1 Then iShow = "Show Normal"
    If BuffLong = 2 Then iShow = "Show Minimized"
    If BuffLong = 3 Then iShow = "Show Maximized"
    zeiger = zeiger + 16
    'ID-List
    If IDList Then
        ReDim iItem(1 To 10)
        Get ff, zeiger + 1, intLänge
        BOL = zeiger + intLänge + 2
        zeiger = zeiger + 2
        Do
            i = i + 1
            Get ff, zeiger + 1, intLänge
            BuffStr = ""
            If i = 2 Then
                k = k + 1
                BuffStr = "   "
                Get ff, zeiger + 4, BuffStr
               iItem(k) = BuffStr
            ElseIf i > 2 Then
                k = k + 1
                If UBound(iItem) < k Then _
                    ReDim Preserve iItem(1 To k)
                Get ff, zeiger + 15, BuffByte
                Do While BuffByte <> Chr(0)
                     BuffStr = BuffStr & BuffByte
                     Get ff, , BuffByte
                Loop
                iItem(k) = BuffStr
            End If
            zeiger = zeiger + intLänge
        Loop While (zeiger + 3) < BOL
        If k Then
            ReDim Preserve iItem(1 To k)
        Else
            ReDim iItem(0)
        End If
    End If
    'Alle folgenden Offsets beginnen ab BOL
    zeiger = BOL
    If LocationList Then
        zeiger = zeiger + 8
        Get ff, zeiger + 1, VolumeFlag
        Get ff, , offsetVol
        Get ff, , OffsetLocalPath
        Get ff, , OffsetNetzwerk
        Get ff, , OffsetFinalPath
        zeiger = zeiger + 20
        'Volumeinfos
        If VolumeFlag And 1 Then
            zeiger = BOL + offsetVol
            Get ff, zeiger + 1, VolLänge
            zeiger = zeiger + 4
            Get ff, zeiger + 1, BuffLong
            Select Case BuffLong
                Case 0
                    iVolumeart = "Unbekannt"
                Case 1
                    iVolumeart = "NoRoot"
                Case 2
                    iVolumeart = "Removeable"
                Case 3
                    iVolumeart = "Harddisk"
                Case 4
                    iVolumeart = "Netzwerk-Drive"
                Case 5
                    iVolumeart = "CD-Rom"
                Case 6
                    iVolumeart = "Ramdrive"
            End Select
            'Serial Number BuffLong
            Get ff, , BuffLong
            iVolumeSerial = SignedLongToUnsignedCur(BuffLong)
            zeiger = zeiger + 12
            'Volumename
            iLocalVolumeName = String(BOL + offsetVol _
                + VolLänge - zeiger, 0)
            Get ff, zeiger + 1, iLocalVolumeName
            'Local Pfad
            zeiger = BOL + OffsetLocalPath
            Get ff, zeiger + 1, BuffByte
            iLocalPath = ""
            Do While BuffByte <> Chr(0)
                 iLocalPath = iLocalPath & BuffByte
                 Get ff, , BuffByte
            Loop
            zeiger = zeiger + Len(iLocalPath) + 1
        End If
        'Netzwerk-Volumeinfos
        If VolumeFlag And 2 Then
            zeiger = BOL + OffsetNetzwerk
            Get ff, zeiger + 1, VolLänge
            zeiger = zeiger + 20
            Get ff, zeiger + 1, BuffByte
            iShareName = ""
            Do While BuffByte <> Chr(0)
                 iShareName = iShareName & BuffByte
                 Get ff, , BuffByte
            Loop
            zeiger = zeiger + Len(iShareName) + 1
        End If
        'Final Path Name
        zeiger = BOL + OffsetFinalPath
        Get ff, zeiger + 1, BuffByte
        iFinalPath = ""
        Do While BuffByte <> Chr(0)
             iFinalPath = iFinalPath & BuffByte
             Get ff, , BuffByte
        Loop
        zeiger = zeiger + Len(iFinalPath) + 1
        'Description
        If Beschreibung = True Then
            Get ff, zeiger + 1, intLänge
            ReDim ArrBuff(1 To intLänge * 2)
            Get ff, , ArrBuff
            iDescription = ArrBuff
            zeiger = zeiger + 2 + intLänge * 2
        End If
        'Relativer Pfad
        If RelPfad = True Then
            Get ff, zeiger + 1, intLänge
            ReDim ArrBuff(1 To intLänge * 2)
            Get ff, , ArrBuff
            iRelativePath = ArrBuff
            zeiger = zeiger + 2 + intLänge * 2
        End If
        'Workdir
        If WorkDir = True Then
            Get ff, zeiger + 1, intLänge
            ReDim ArrBuff(1 To intLänge * 2)
            Get ff, , ArrBuff
            iWorkdirectory = ArrBuff
            zeiger = zeiger + 2 + intLänge * 2
        End If
        'Commandline
        If CommandlineArgs = True Then
            Get ff, zeiger + 1, intLänge
            ReDim ArrBuff(1 To intLänge * 2)
            Get ff, , ArrBuff
            iCommandlineArgs = ArrBuff
            zeiger = zeiger + 2 + intLänge * 2
        End If
        'Iconpfad
        If UserdefIcon = True Then
            Get ff, zeiger + 1, intLänge
            ReDim ArrBuff(1 To intLänge * 2)
            Get ff, , ArrBuff
            iIconPath = ArrBuff
            zeiger = zeiger + 2 + intLänge * 2
        End If
    End If
Close
End Sub

Private Function SignedLongToUnsignedCur(x As Long) As Currency

Dim a As DoubleLong, b As SingleCur
a.a = x
LSet b = a
SignedLongToUnsignedCur = b.a * 10000
End Function

Public Property Let Linkpath(ByVal vNewValue As String)

    Zurücksetzen
    iLinkpath = vNewValue
    ParseLnk
End Property

Public Property Get Itemlist()

    Itemlist = iItem
End Property

Public Property Get VolumeSerial() As Currency

    VolumeSerial = iVolumeSerial
End Property

Public Property Get VolumeArt() As String

    VolumeArt = iVolumeart
End Property

Public Property Get ShowModus() As String

    ShowModus = iShow
End Property

Public Property Get Filelength() As Long

    Filelength = iFilelänge
End Property

Public Property Get Kompressed() As Boolean

    Kompressed = iKomprimiert
End Property

Public Property Get Temporary() As Boolean

    Temporary = iTemp
End Property

Public Property Get Archive() As Boolean

    Archive = iArchive
End Property

Public Property Get Directory() As Boolean

    Directory = iDirectory
End Property

Public Property Get System() As Boolean

    System = iSystem
End Property

Public Property Get Hidden() As Boolean

    Hidden = iHidden
End Property

Public Property Get ReadOnly() As Boolean

    ReadOnly = iReadOnly
End Property

Public Property Get Encrypted() As Boolean

    Encrypted = iEncrypted
End Property

Public Property Get CreationTime() As String

    CreationTime = iCreationTime
End Property

Public Property Get LastAccessTime() As String

    LastAccessTime = iLastAccessTime
End Property

Public Property Get LastModifyTime() As String

    LastModifyTime = iLastModifyTime
End Property

Public Property Get CommandlineArgs() As String

    CommandlineArgs = iCommandlineArgs
End Property

Public Property Get IconNumber() As String

    IconNumber = iIconNumber
End Property

Public Property Get IconPath() As String

    IconPath = iIconPath
End Property

Public Property Get RelativePath() As String

    RelativePath = iRelativePath
End Property

Public Property Get Workdirectory() As String

    Workdirectory = iWorkdirectory
End Property

Public Property Get GUID() As String

    GUID = iGUID
End Property

Public Property Get FinalPath() As String

    FinalPath = iFinalPath
End Property

Public Property Get LocalVolumeName() As String

    LocalVolumeName = iLocalVolumeName
End Property

Public Property Get LocalPath() As String

    LocalPath = iLocalPath
End Property

Public Property Get NetworkVolumeName() As String

    NetworkVolumeName = iNetworkVolumeName
End Property

Public Property Get ShareName() As String

    ShareName = iShareName
End Property

Public Property Get Description() As String

    Description = iDescription
End Property

Private Sub Zurücksetzen()

iFinalPath = ""
iLocalVolumeName = ""
iDescription = ""
iGUID = ""
iCommandlineArgs = ""
iWorkdirectory = ""
iIconPath = ""
iIconNumber = ""
iLocalVolumeName = ""
iLocalPath = ""
iNetworkVolumeName = ""
iShareName = ""
iCreationTime = ""
iLastAccessTime = ""
iLastModifyTime = ""
iRelativePath = ""
iEncrypted = False
iReadOnly = False
iHidden = False
iSystem = False
iDirectory = False
iArchive = False
iTemp = False
iKomprimiert = False
iFilelänge = 0
iShow = ""
iVolumeart = ""
iVolumeSerial = 0
End Sub

Private Function myLocalTimeToDateString( _
    MyTime As FILETIME) As String

Dim myLocalTime As SYSTEMTIME
'Ländereinstellung Zeit beachten
FileTimeToLocalFileTime MyTime, MyTime
'In eine Systemzeit umwandeln
FileTimeToSystemTime MyTime, myLocalTime
'In einen formatierten String umwandeln
myLocalTimeToDateString = Format( _
    DateSerial(myLocalTime.wYear, _
    myLocalTime.wMonth, myLocalTime.wDay) _
    + TimeSerial(myLocalTime.wHour, _
    myLocalTime.wMinute, myLocalTime.wSecond) _
    , "DD.MM.YYYY hh:nn:ss")
End Function