#include <String.au3>

;MsgBox(0, '', _MSIShortcutTarget(@DesktopDir&"\Microsoft Office Word 2003.lnk"))
;===============================================================================
;
; 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
;
;===============================================================================
;

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