MsiGetShortcutTarget MSI LNK文件不返回任何组件ID

我试图以编程方式找到为给定的MSI lnk文件(通告的快捷方式)运行的exe文件。 我使用了类似于答案中显示的方法有没有办法解决.lnk目标适用于最终在c:\ windows \ installer中的链接? 。 这种方法适用于大多数MSI lnk文件。 不幸的是,有少数lnk文件运行正常,但MsiGetShortcutTarget不返回任何组件ID。 因此,对MsiGetComponentPath的后续调用将返回InvalidArg。

这是我正在使用的代码(取自此处 ):

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; } } 

我的机器上的示例是C:\ ProgramData \ Microsoft \ Windows \ Start Menu \ Programs \ Microsoft Office 2013 \ Office 2013 Tools \ Office 2013 Language Preferences.lnk

产品编号:{91150000-0011-0000-0000-0000000FF1CE}functionID:SetLanguageFiles

我相信IShellLink接口不能用于返回MSI广告快捷方式的runnable exe,我尝试这样做会返回包含图标资源的exe的路径。

显然,操作系统可以找到适当的exe(在这种情况下,它是C:\ Program Files(x86)\ Microsoft Office \ Office15 \ SETLANG.EXE)。

如何使用代码获取与此lnk文件关联的exe文件?

当没有从MsiGetShortcutTarget返回组件ID时,可以从MSI数据库获取组件ID。 一种方法是使用WiX DTF,如下所示: https : //stackoverflow.com/a/34680682/3051702 。

然后可以在对MsiGetComponentPath的调用中使用返回的组件ID。 或者,可以直接使用本机方法。