我想解决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下失败,我不知道它为什么出错。
答案 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的工作原理,你可以查看代码。