- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我找到了一个 nice Powershell function在 GitHub 上,它使用 WindowsInstaller.Installer COM 对象来查询已安装的应用程序,并非常漂亮地列出了所有详细信息和属性。但是,我不想使用 Powershell 我想创建一个 exe。
我不想搜索注册表,也不想使用 WMI。我想使用在 powershell 脚本和我找到的另一个 vbscript 中使用的完全相同的方法。确实存在一个名为 WindowsInstaller.Installer 的 COM 对象。它确实存在,但由于某种原因,我找不到一个关于在使用 C# 在 Visual Studio 中导入 msi.dll 后如何访问它的示例。
有谁知道这个问题的答案?
在 Visual Studio 中,为 WindowsInstaller 添加 COM 引用的 WindowsInstaller.Installer 引用只是一种类型,仅此而已。它不包含名为“GetType”的方法,并且尝试将此 PowerShell 转换为 C# 无法正常工作。
我也不知道是什么@{}
意味着但我猜它意味着哈希表。
我试图强制以下情况的可悲尝试:
private void Form1_Load(object sender, EventArgs e)
{
Type installerType = Type.GetType("WindowsInstaller.Installer");
Installer installerObj = (Installer)Activator.CreateInstance(installerType);
WindowsInstaller.Installer installer = installerObj as WindowsInstaller.Installer;
var type = installer.GetType();
var Products = type.InvokeMember("Products", System.Reflection.BindingFlags.GetProperty, null, installer, null) as IEnumerable<object>;
foreach (var product in Products)
{
Hashtable hash = new Hashtable();
hash.Add("ProductCode", product);
string[] Attributes = { "Language", "ProductName", "PackageCode", "Transforms", "AssignmentType", "PackageName", "InstalledProductName", "VersionString", "RegCompany", "RegOwner", "ProductID", "ProductIcon", "InstallLocation", "InstallSource", "InstallDate", "Publisher", "LocalPackage", "HelpLink", "HelpTelephone", "URLInfoAbout", "URLUpdateInfo" };
foreach (var attribute in Attributes)
{
object[] thing = { product, attribute };
var details = type.InvokeMember("ProductInfo", System.Reflection.BindingFlags.GetProperty, null, installer, thing);
hash.Add(attribute, details);
}
new ??????????
}
}
最佳答案
你说得对 @{}
,它是一个新的哈希表。我认为对于您想要的东西,您只需创建一个列表,并且通过迭代收集属性的每个产品,您都可以将其添加到该列表中
Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
Installer installerObj = (Installer)Activator.CreateInstance(installerType);
WindowsInstaller.Installer installer = installerObj as WindowsInstaller.Installer;
var Products = installerObj.Products;
List<Hashtable> ProductCollection = new List<Hashtable>();
foreach (var product in Products)
{
Hashtable hash = new Hashtable();
hash.Add("ProductCode", product);
string[] Attributes = { "Language", "ProductName", "PackageCode", "Transforms", "AssignmentType", "PackageName", "InstalledProductName", "VersionString", "RegCompany", "RegOwner", "ProductID", "ProductIcon", "InstallLocation", "InstallSource", "InstallDate", "Publisher", "LocalPackage", "HelpLink", "HelpTelephone", "URLInfoAbout", "URLUpdateInfo" };
foreach (var attribute in Attributes)
{
try
{
var details = installer.ProductInfo[product.ToString(), attribute.ToString()];
hash.Add(attribute, details);
}
catch
{
}
}
ProductCollection.Add(hash);
}
public class MSIInfo
{
public string ProductCode { get; set; }
public string Language { get; set; }
public string ProductName { get; set; }
public string PackageCode { get; set; }
public string Transforms { get; set; }
public string AssignmentType { get; set; }
public string PackageName { get; set; }
public string InstalledProductName { get; set; }
public string VersionString { get; set; }
public string RegCompany { get; set; }
public string RegOwner { get; set; }
public string ProductID { get; set; }
public string ProductIcon { get; set; }
public string InstallLocation { get; set; }
public string InstallSource { get; set; }
public string InstallDate { get; set; }
public string Publisher { get; set; }
public string LocalPackage { get; set; }
public string HelpLink { get; set; }
public string HelpTelephone { get; set; }
public string URLInfoAbout { get; set; }
public string URLUpdateInfo { get; set; }
public override string ToString()
{
return $"{ProductName} - {ProductCode}";
}
public static IEnumerable<MSIInfo> GetProducts()
{
Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
Installer installerObj = (Installer)Activator.CreateInstance(installerType);
WindowsInstaller.Installer installer = installerObj as WindowsInstaller.Installer;
var Products = installerObj.Products;
List<MSIInfo> ProductCollection = new List<MSIInfo>();
foreach (var product in Products)
{
MSIInfo msi = new MSIInfo();
msi.ProductCode = product.ToString();
foreach (var property in msi.GetType()?.GetProperties())
{
try
{
if (property.Name != "ProductCode")
{
string val = installer.ProductInfo[product.ToString(), property.Name];
property.SetValue(msi, val);
}
}
catch (System.Runtime.InteropServices.COMException)
{
}
}
ProductCollection.Add(msi);
}
return ProductCollection;
}
}
var Products = MSIInfo.GetProducts();
关于c# - 在 C# 中访问 WindowsInstaller.Installer COM 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54224817/
我正在尝试在构建服务器上编译 WiX 安装程序(它具有自定义操作,我怀疑这是问题的根源),但出现以下错误: c:\Windows\Microsoft.NET\Framework64\v4.0.30
我正在使用 C#。我创建了一个 Wix 安装程序和一个自定义操作来支持 wix 安装程序。现在我正在尝试创建一个仅对 CustomAction 进行单元测试,而没有 LUX。 我尝试了许多不同的方式,
我有一个 Windows Installer (VS 2008) 项目,我想创建一个非常简单的构建后事件,它只打开目标文件夹,并选择安装程序。 所以我在 PostBuildEvent 字段中输入了以下
我有一个 Windows Installer (VS 2008) 项目,我想创建一个非常简单的构建后事件,它只打开目标文件夹,并选择安装程序。 所以我在 PostBuildEvent 字段中输入了以下
我找到了一个 nice Powershell function在 GitHub 上,它使用 WindowsInstaller.Installer COM 对象来查询已安装的应用程序,并非常漂亮地列出了
我的wxs文件中的两个组件标签如下 = 602]]> 但是我收到如下错误 ICE08: Component: Comp.Comp2 has a duplicate GUID: {29
我想读取 MSI 文件(Windows 安装程序包)。我编写了一个如下所示的函数,它采用两个输入参数:msifileName 和表名称并返回一个数据表,它是 MSI 表之一。 public DataT
我是一名优秀的程序员,十分优秀!