VBS 按我的预期工作,但是使用 C# 的 COM API 和 DTF 都无法找到 InstallLocation。以下是我到目前为止所做的事情。
谢谢这个帖子,我能够使用 vbs 找到注册表上不可用的 InstallLocation。我知道 vbs 正在调用可用的 COM API%WINDIR%\system32\msi.dll
.
C# COM API
所以我就想用C#来调用这个方法。但它失败了。即使我可以确认存在和安装,它也无法打开产品 GUID 之一(我检查了三次)。
注意:有些产品没有抛出异常,并且正确找到了 InstallLocation。这还不是全部。
以下是我的代码。
static Dictionary<string, string> FindInstallLocationsCOM(Dictionary<string, string> products)
{
var locationDictionary = new Dictionary<string, string>();
// Get the type of the Windows Installer object
Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
// Create the Windows Installer object
Object installerObj = Activator.CreateInstance(installerType);
Installer installer = installerObj as Installer;
foreach (var product in products)
{
try
{
var session = installer.OpenProduct(product.Value);
if (session != null)
{
session.DoAction("CostInitialize");
session.DoAction("CostFinalize");
var installLocation = session.Property["INSTALLLOCATION"];
MessageBox.Show(product.Key + "\n" + "Product Code : " + product.Value + "\n" + "Install Location : " + installLocation);
locationDictionary.Add(product.Key, installLocation);
}
}
catch (Exception e)
{
MessageBox.Show("Error : Could not open Product " + e.Message + "\n" + "Product : " + product.Key + "\n" + "Product Code : " + product.Value);
}
}
return locationDictionary;
}
好吧,这不起作用,让我们尝试一下 DTF。
C# DTF
但这也并不成功。以下是我的代码。这不会触发异常,甚至无法通过 COM API 检测到的异常也能够检测到自身,但 InstallLocation 属性为空字符串。
注意:有些产品确实填充了 InstallLocation 属性。这还不是全部。
static Dictionary<string,string> FindInstallLocation(Dictionary<string,string> products)
{
var locationDictionary = new Dictionary<string, string>();
foreach (var product in products)
{
try
{
var installed = new ProductInstallation(product.Value);
if (installed != null)
{
var installLocation = installed.InstallLocation;
MessageBox.Show(product.Key + "\n" + "Product Code : " + product.Value + "\n" + "Install Location : " + installLocation);
locationDictionary.Add(product.Key, installLocation);
}
else
{
MessageBox.Show(product.Key + "\n" + "Product Code : " + product.Value + "\n" + "Is not installed");
}
}
catch (Exception e)
{
MessageBox.Show("Error : " + e.Message + "\n" + "Product : " + product.Key + "\n" + "Product Code : " + product.Value);
}
}
return locationDictionary;
}
为什么 VBS 能够检测到 InstallLocation,而 C# 却无法检测到?我缺少什么?
我不能使用VBS的原因是因为除非我使用vb.net,否则try catch不可用。