c#dllimport of MsiGetShortcutTarget(msi.dll)在Windows 7下失败,错误1603

时间:2010-12-20 14:05:28

标签: c# windows-installer dllimport

我想解决c#中广告的MSI快捷方式,如下所述: How to parse "special" .lnk files, aka. MSI shortcuts aka. Windows Installer advertised shortcuts using C#

[DllImport("msi.dll", CharSet = CharSet.Auto)]
private static extern UInt32 MsiGetShortcutTarget(
    string szShortcutTarget,
    [Out] StringBuilder szProductCode,
    [Out] StringBuilder szFeatureId,
    [Out] StringBuilder szComponentCode);

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

    UInt32 res = MsiGetShortcutTarget(file, product, feature, component);
    ...
}

我使用VS 2010并尝试使用“平台目标”和/或“目标框架”的不同设置。在Windows 7下,MsiGetShortcutTarget始终返回1603(安装期间发生致命错误)。

我尝试用c ++做同样的事情,我可以解决快捷方式,一切都很好。我还测试了一个msi.dll,我是从Windows XP复制的,这个dll可以用C#代码解析快捷方式。我不知道为什么c#代码不适用于Windows 7下的msi.dll。

我使用已知的产品GUID和组件GUID测试MsiGetComponentPath以使用dll解析c#中的目标路径,为MsiGetShortcutTarget返回1603并且它完美地工作。所以只有MsiGetComponentPath在Windows 7下失败,我不知道它为什么出错。

2 个答案:

答案 0 :(得分:0)

这似乎与COM初始化的方式有关。

如果我将[STAThread]添加到我的Main方法,它可以正常工作(如果您实际使用StringBuilder而不是char[]作为参数:-),但是使用MTA时,我得到的返回值为1603。

答案 1 :(得分:0)

我强烈建议您查看WiX的部署工具基金会。它有一个非常好的互操作库,由MSFT员工开发,可以轻松调用MSI。

例如,Microsoft.Deployment.WindowsInstaller命名空间有一个Installer类,它公开一个静态方法ShortcutTarget GetShortcutTarget(字符串快捷方式)。然后,ShortcutTarget类具有ComponentCode,Feature和ProductCode的访问器。

Additionalyl这是一个开源项目,所以如果你真的想知道P / Invoke的工作原理,你可以查看代码。