Pfad von MSI Verknüpfungen

  • Bei von MSI erstellten Verknüpfungen zeigt der Pfad auf die Exe, die sie erstellt hat. Um den Pfad zum eigentlichen Ziel hearuszubekommen, muss man einige DLLCalls machen. Daraus habe ich mal eine Funktion geschrieben:

    Spoiler anzeigen
    [autoit]

    #include <String.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _FileGetShortcutEx($link)
    ; Description:: Gets information from a ShortcutFile and gets the Path of MSi installed Shortcuts, too
    ; Parameter(s): $link : Path of the Shortcut
    ; Requirement(s): ?
    ; Return Value(s): Success: Array like FileGetShortcut
    ; Error: 0
    ; Error Code(s): like FileGetShortCut()
    ;
    ; Author(s): Prog@ndy
    ;
    ;===============================================================================
    ;
    Func _FileGetShortcutEx($link)
    Local $lnk = FileGetShortcut ($link )
    If @error Then Return SetError(@error,0,0)
    Local $msitest = _MSIShortcutTarget($link)
    If Not @error Then $lnk[0] = $msitest
    Return $lnk
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;===============================================================================
    ;
    ; Function Name: _MSIShortcutTarget($link)
    ; Description:: Gets the Path from a Shrtcut created with MSI
    ; Parameter(s): $link : Path of the Shortcut
    ; Requirement(s): ?
    ; Return Value(s): Success: Executable Path
    ; Error: 0
    ; Error Code(s): 1-3 : like DllCall
    ; 4 : Path does not exist OR it's not a MSI Shortcut
    ; 5 : Component is not installed (correctly)
    ;
    ; Author(s): Prog@ndy
    ;
    ;===============================================================================
    ;

    [/autoit] [autoit][/autoit] [autoit]

    Func _MSIShortcutTarget($link)
    Local Const $MsiDllName = 'msi.dll'
    Local Const $INSTALLSTATE_ABSENT = 2; ;// uninstalled
    Local Const $INSTALLSTATE_LOCAL = 3; ;// installed on local drive
    Local Const $INSTALLSTATE_SOURCE = 4; ;// run from source, CD or net
    Local Const $INSTALLSTATE_SOURCEABSENT = -4; ;// run from source, source is unavailable
    Local Const $INSTALLSTATE_NOTUSED = -7; ;// component disabled
    Local Const $INSTALLSTATE_INVALIDARG = -2; ;// invalid function argument
    Local Const $INSTALLSTATE_UNKNOWN = -1; ;// unrecognized product or feature
    Const $ERROR_SUCCESS = 0
    Local $500Chr0 = _StringRepeat(Chr(0),500)
    Local $shortcut,$szComponentCode,$szFeatureId,$szProductCode,$installstate

    $shortcut = Dllcall($MsiDllName,"int","MsiGetShortcutTarget","str",$link,"str",$500Chr0,"str",$500Chr0,"str",$500Chr0)
    If @error Then Return SetError(@error,0,0)
    If $shortcut[0] <> $ERROR_SUCCESS Then Return SetError(4,0,0)
    $szProductCode = $shortcut[2]
    $szFeatureId = $shortcut[3]
    $szComponentCode = $shortcut[4]
    $installstate = Dllcall($MsiDllName,"int","MsiGetComponentPath","str",$szProductCode,"str",$szComponentCode,"str",$500Chr0,"dword*",500)
    If @error Then Return SetError(@error,0,0)
    If $installstate[0] = $INSTALLSTATE_LOCAL Or $installstate[0] = $INSTALLSTATE_SOURCE Then
    Switch StringLeft($installstate[3],3)
    Case "00:","20:"
    $installstate[3] = "HKEY_CLASSES_ROOT" & StringMid($installstate[3],4)
    Case "01:","21:"
    $installstate[3] = "HKEY_CURRENT_USER" & StringMid($installstate[3],4)
    Case "02:","22:"
    $installstate[3] = "HKEY_LOCAL_MACHINE" & StringMid($installstate[3],4)
    Case "03:","23:"
    $installstate[3] = "HKEY_USERS" & StringMid($installstate[3],4)
    EndSwitch
    Return $installstate[3]
    EndIf
    Return SetError(5,0,0)
    EndFunc

    [/autoit]

    //Edit: Registry-Pfae werden jetzt auch richtig dargestellt

    //Edit2: Zusätzliche Funktion + Anhang