gpt4 book ai didi

c# - 如何在 C# 中将 WindowsInstaller.Record 转换为 System.Data.Dataset 或数据表(在读取 MSI 文件时)

转载 作者:太空宇宙 更新时间:2023-11-03 18:11:34 26 4
gpt4 key购买 nike

我想读取 MSI 文件(Windows 安装程序包)。我编写了一个如下所示的函数,它采用两个输入参数:msifileName 和表名称并返回一个数据表,它是 MSI 表之一。

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;
}

使用上面的代码片段,记录的行数和列数是未知的。所以我只静态返回四列。我想返回记录中的 MSI 表的所有行和列。

所以请告诉我如何将 View 或记录的输出转换为数据集,然后绑定(bind)到数据表。或者有没有其他方法可以返回所有的行和列。提前致谢。

最佳答案

这是使用互操作类型而不是 DTF 类型的类似逻辑。如您所见,还有很多工作要做。它也更加脆弱,因为涉及 COM 而不是 P/Invoke。此外,如果您可以消除创建 ADO.NET DataTable 的要求,DTF 将支持 LINQ 查询和数据绑定(bind)。换句话说,我写这篇文章只是为了好玩。我永远不会在实际代码中使用此方法。

 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;
}

关于c# - 如何在 C# 中将 WindowsInstaller.Record 转换为 System.Data.Dataset 或数据表(在读取 MSI 文件时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14020285/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com