如何阅读在C#MSI属性(How to read MSI properties in c#)

2019-07-05 21:29发布

我想读我用下面的代码在C#中的桌面application.I MSI的属性:

    public static string GetMSIProperty( string msiFile, string msiProperty)
    {
        string retVal= string.Empty ;

        Type classType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
        Object installerObj = Activator.CreateInstance(classType);
        WindowsInstaller.Installer installer = installerObj as WindowsInstaller.Installer;

        Database database = installer.OpenDatabase("C:\\DataP\\sqlncli.msi",0 );   

        string sql = String.Format("SELECT Value FROM Property WHERE Property=’{0}’", msiProperty);

        View view = database.OpenView(sql);

        Record record = view.Fetch();

        if (record != null)
        {
            retVal = record.get_StringData(1);
        }
        else
            retVal = "Property Not Found";

        return retVal;            
    }

但我得到错误的System.Runtime.InteropServices.COMException了未处理。

该sqlncli.msi文件被物理放置在C:\ DATAP位置。 虽然调试我发现,数据库不包含installer.OpenDatabase()语句后的数据。

请建议我如何解决这个问题,在C#中得到MSI属性。

提前致谢。

Answer 1:

Windows安装程序XML的部署工具基金会(WiX的DTF)是来自微软的开源项目,该项目包括Microsoft.Deployment.WindowsInstaller MSI互操作库。 它更容易和更可靠的用这个来做这些类型的查询。 它甚至有一个LINQ到MSI提供商,可以让你把MSI表作为实体和编写针对他们的查询。

using System;
using System.Linq;
using Microsoft.Deployment.WindowsInstaller;
using Microsoft.Deployment.WindowsInstaller.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            using(var database = new QDatabase(@"C:\tfs\iswix.msi", DatabaseOpenMode.ReadOnly))
            {
                var properties = from p in database.Properties
                                 select p;

                foreach (var property in properties)
                {
                    Console.WriteLine("{0} = {1}", property.Property, property.Value);
                }
            }

            using (var database = new Database(@"C:\tfs\iswix.msi", DatabaseOpenMode.ReadOnly))
            {
                using(var view = database.OpenView(database.Tables["Property"].SqlSelectString))
                {
                    view.Execute();
                    foreach (var rec in view) using (rec)
                    {
                        Console.WriteLine("{0} = {1}", rec.GetString("Property"), rec.GetString("Value"));
                    }
                }
            }

            Console.Read();
        }
    }
}


Answer 2:

SQL字符串不正确。 它应该是:

SELECT `Value` FROM `Property` WHERE `Property`.`Property` = ’{0}’


Answer 3:

我试图重新使用这个代码,我不得不做出度日Devashri发布工作的代码唯一的变化是这一行:

string sql = String.Format("SELECT `Value` FROM `Property` WHERE `Property`='{0}'", msiProperty);

当心单引号!



Answer 4:

我这样做是在下列方式:

String inputFile = @"C:\\Rohan\\sqlncli.msi";

// Get the type of the Windows Installer object
Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");

// Create the Windows Installer object
WindowsInstaller.Installer installer = (WindowsInstaller.Installer)Activator.CreateInstance(installerType);

// Open the MSI database in the input file
Database database = installer.OpenDatabase(inputFile, 0);

// Open a view on the Property table for the version property
View view = database.OpenView("SELECT * FROM _Tables");

// Execute the view query
view.Execute(null);

// Get the record from the view
Record record = view.Fetch();

while (record != null)
{
    Console.WriteLine(record.get_StringData(0) + '=' + record.get_StringData(1) + '=' + record.get_StringData(2) + '=' + record.get_StringData(3));
    record = view.Fetch();
}

而它为我工作。



文章来源: How to read MSI properties in c#