C# ataTable(表名); 类型installerType=Type.GetTypeFromProgID(“WindowsInstaller.Installer”); Installer安装程序=(WindowsInstaller.Installer)Ac

C# ataTable(表名); 类型installerType=Type.GetTypeFromProgID(“WindowsInstaller.Installer”); Installer安装程序=(WindowsInstaller.Installer)Ac,c#,datatable,dataset,windows-installer,C#,Datatable,Dataset,Windows Installer,ataTable(表名); 类型installerType=Type.GetTypeFromProgID(“WindowsInstaller.Installer”); Installer安装程序=(WindowsInstaller.Installer)Activator.CreateInstance(installerType); Database Database=installer.OpenDatabase(msfile,MsiOpenDatabaseMode.msiopendatabase

ataTable(表名); 类型installerType=Type.GetTypeFromProgID(“WindowsInstaller.Installer”); Installer安装程序=(WindowsInstaller.Installer)Activator.CreateInstance(installerType); Database Database=installer.OpenDatabase(msfile,MsiOpenDatabaseMode.msiopendatabasemoderedeadOnly); string sqlQuery=string.Format(“从{0}中选择*表名”); View=database.OpenView(sqlQuery); view.Execute(null); 记录名称=view.ColumnInfo[MsiColumnInfo.msiColumnInfoNames]; 记录类型=view.ColumnInfo[MsiColumnInfo.msiColumnInfoTypes]; 记录行=view.Fetch(); 对于(int index=1;index感谢Yan的回复,但我的组织拒绝访问上述工具集链接。有没有其他方法可以动态填充数据表?嗯,似乎最好的方法是尝试解释为什么您需要访问该表,而不是仅仅因为访问被禁止而寻求其他方法。。。DTF是使用MSI数据库的最佳选择,据我所知,DTF是唯一让我费心的选择。另一个问题是,为什么它需要是一个数据表?许多年前,我为MSI编写了一个ADO.NET提供程序,它将结果作为DataTable对象返回,但现在DTF支持Linq to MSI,我看不出它有什么用处。感谢Yan的回复,但在我的组织中,对上述工具集链接的访问被拒绝。有没有其他方法可以动态填充数据表?嗯,似乎最好的方法是尝试解释为什么您需要访问该表,而不是仅仅因为访问被禁止而寻求其他方法。。。DTF是使用MSI数据库的最佳选择,据我所知,DTF是唯一让我费心的选择。另一个问题是,为什么它需要是一个数据表?许多年前,我为MSI编写了一个ADO.NET提供程序,它将结果作为DataTable对象返回,但现在DTF支持Linq to MSI,我看不出它有什么用处。评论“疯狂有它的局限性”。值得+5!反模式的精彩演示,克里斯托弗!谢谢,燕。你所要做的就是使用WPF和Linq-to-MSI数据绑定编写几个演示,从而认识到编写一个像Orca这样的应用程序是当今的儿童游戏。“疯狂有它的局限性。”这条评论值得+5!反模式的精彩演示,克里斯托弗!谢谢,燕。我们所要做的就是使用WPF和Linq-to-MSI数据绑定编写几个演示,以认识到编写像Orca这样的应用程序现在是儿戏。我尝试做同样的事情,但我得到:“系统无法打开指定的设备或文件。Database=“Setup.MSI”您必须传入一个有效的msiPath,该msiPath存在并且您有权访问。我有这个msiPath,但它仍然失败:string path=@“c:\Temp\WixSqlDeployment\Setup\bin\Debug\Setup.msi”;db=新数据库(路径,DatabaseOpenMode.Direct);但是,当我更改DatabaseOpenMode时。若要只读,它将通过,但我无法更新表。有关我的完整代码,请参见以下内容:我正在尝试执行相同的操作,但我得到:“系统无法打开指定的设备或文件。Database=“Setup.msi”“您必须传入一个存在且您有权访问的有效msiPath。我有此权限,但仍然失败:string path=@“c:\Temp\WixSqlDeployment\Setup\bin\Debug\Setup.msi”;db=new Database(path,DatabaseOpenMode.Direct);但是,当我更改DatabaseOpenMode.TO ReadOnly时,它会通过,但我无法更新表。有关完整代码,请参阅以下内容:
public DataTable ReadMsiPropertyTable(string msiFile, string tableName)
    {            
        Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");

        WindowsInstaller.Installer installer = (WindowsInstaller.Installer)Activator.CreateInstance(installerType);

        Database database = installer.OpenDatabase(msiFile, 0);

        string sqlQuery = String.Format("SELECT * FROM {0}",tableName);

        View view = database.OpenView(sqlQuery);

        view.Execute(null);

        Record record = view.Fetch();

        DataTable msiPropertyTable = new DataTable();

        msiPropertyTable.Columns.Add("Column1", typeof(string));
        msiPropertyTable.Columns.Add("Column2", typeof(string));
        msiPropertyTable.Columns.Add("Column3", typeof(string));
        msiPropertyTable.Columns.Add("Column4", typeof(string));

        while (record != null)
        {
            int fieldCount;
            fieldCount = record.FieldCount;

            msiPropertyTable.Rows.Add(record.get_StringData(0), record.get_StringData(1), record.get_StringData(2), record.get_StringData(3));                
            record = view.Fetch();
        }
        return msiPropertyTable;
    }
var db = new Database("path\to\MSI");
public static DataTable TableToDataTable( string msiPath, string tableName )
{
    DataTable dataTable = null;
    using(var database = new Database(msiPath, DatabaseOpenMode.ReadOnly))
    {
        using(var view = database.OpenView("SELECT * FROM `{0}`", tableName))
        {
            view.Execute();

            dataTable = new DataTable(tableName);
            foreach (var column in view.Columns)
            {
                dataTable.Columns.Add(column.Name, column.Type);
            }

            foreach (var record in view) using (record)
            {
                var row = dataTable.NewRow();
                foreach (var column in view.Columns)
                {
                    row[column.Name] = record[column.Name];
                }
                dataTable.Rows.Add(row);
            }
        }
    }
    return dataTable;
}
 public static DataTable ReadMsiPropertyTable(string msiFile, string tableName)
        {
            DataTable dataTable = new DataTable(tableName);
            Type installerType = Type.GetTypeFromProgID("WindowsInstaller.Installer");
            Installer installer = (WindowsInstaller.Installer)Activator.CreateInstance(installerType);
            Database database = installer.OpenDatabase(msiFile, MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly);

            string sqlQuery = String.Format("SELECT * FROM {0}", tableName);
            View view = database.OpenView(sqlQuery);
            view.Execute(null);

            Record names = view.ColumnInfo[MsiColumnInfo.msiColumnInfoNames];
            Record types = view.ColumnInfo[MsiColumnInfo.msiColumnInfoTypes];
            Record row = view.Fetch();

            for (int index = 1; index < names.FieldCount+1; index++)
            {
                string columnName = names.get_StringData(index);
                string columnSpec = types.get_StringData(index);

                switch (columnSpec.Substring(0, 1).ToLower())
                {
                    case "s":
                        dataTable.Columns.Add(columnName, typeof(String));
                        break;

                    case "l":
                        dataTable.Columns.Add(columnName, typeof(String));
                        break;

                    case "i":
                        dataTable.Columns.Add(columnName, typeof(Int32));
                        break;

                    case "v":
                        dataTable.Columns.Add(columnName, typeof (Stream));
                        break;
                }
            }

            while (row != null)
            {
                DataRow dataRow = dataTable.NewRow();
                for (int index = 0; index < dataTable.Columns.Count; index++)
                {

                    if(dataTable.Columns[index].DataType == typeof(String))
                    {
                        dataRow[index] = row.StringData[index + 1];
                    }
                    else if(dataTable.Columns[index].DataType == typeof(Int32))
                    {
                        dataRow[index] = row.IntegerData[index + 1];
                    }
                    else if(dataTable.Columns[index].DataType == typeof(Stream))
                    {
                       // Insanity has it's limits. Not implemented.
                    }
                }
                dataTable.Rows.Add(dataRow);
                row = view.Fetch();
            }
            return dataTable;
        }