MsiGetShortcutTarget MSI LNK files return no component id

馋奶兔 提交于 2019-12-22 10:46:13

问题


I am trying to programmatically find the exe file that is run for a given MSI lnk file (advertised shortcut). I have used an approach similar to that shown in the answer to Is there a way to resolve a .lnk target that works for links that end up in c:\windows\installer?. This approach works fine for the majority of MSI lnk files. Unfortunately there are a minority of lnk files that run fine, but MsiGetShortcutTarget returns no component id. So the subsequent call to MsiGetComponentPath returns InvalidArg.

Here's the code I'm using (taken from here):

public const int MaxFeatureLength = 38;
public const int MaxGuidLength = 38;
public const int MaxPathLength = 1024;

public static string ParseShortcut(string shortcutFilename)
{
    StringBuilder product = new StringBuilder(MaxGuidLength + 1);
    StringBuilder feature = new StringBuilder(MaxFeatureLength + 1);
    StringBuilder component = new StringBuilder(MaxGuidLength + 1);

    var returnValue = MsiGetShortcutTarget(shortcutFilename, product, feature, component);

    if (returnValue != 0)
    {
        return null;
    }

    int pathLength = MaxPathLength;
    StringBuilder path = new StringBuilder(pathLength);

    InstallState installState = MsiGetComponentPath(product.ToString(), component.ToString(), path, ref pathLength);
    if (installState == InstallState.Local)
    {
        return path.ToString();
    }
    else
    {
        return null;
    }
}

An example on my machine is C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft Office 2013\Office 2013 Tools\Office 2013 Language Preferences.lnk

Product id: {91150000-0011-0000-0000-0000000FF1CE} Feature id: SetLanguageFiles

I believe the IShellLink interface cannot be used to return the runnable exe for MSI Advertised Shortcuts and my attempts to do so have returned the path to an exe containing icon resources.

Clearly it is possible for the operating system to locate the appropriate exe (in this case it is C:\Program Files (x86)\Microsoft Office\Office15\SETLANG.EXE).

How do I get which exe file is associated with this lnk file using code?


回答1:


When no component id is returned from MsiGetShortcutTarget, it is possible to get the component id from the MSI database. One way of doing this is to use WiX DTF as shown here: https://stackoverflow.com/a/34680682/3051702.

The returned component id can then be used in a call to MsiGetComponentPath. Alternatively, the native methods could be used directly.



来源:https://stackoverflow.com/questions/34638433/msigetshortcuttarget-msi-lnk-files-return-no-component-id

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!