private static List <MsiColumnDefinition> ReadColumnDefinitions(IntPtr viewHandle) { List <MsiColumnDefinition> columnDefinitions = new List <MsiColumnDefinition>(); Msi.ViewExecute(viewHandle, IntPtr.Zero); IntPtr recordHande; // Get column names Msi.ViewGetColumnInfo(viewHandle, Msi.MsiColInfoType_Names, out recordHande); try { uint columnCount = Msi.RecordGetFieldCount(recordHande); for (int i = 0; i < columnCount; i++) { MsiColumnDefinition columnDefinition = new MsiColumnDefinition(); columnDefinition.Name = Msi.RecordGetString(recordHande, (uint)(i + 1)); columnDefinitions.Add(columnDefinition); } } finally { Msi.CloseHandle(recordHande); } // Get column types Msi.ViewGetColumnInfo(viewHandle, Msi.MsiColInfoType_Types, out recordHande); try { uint columnCount = Msi.RecordGetFieldCount(recordHande); for (int i = 0; i < columnCount; i++) { string columnTypeDescriptor = Msi.RecordGetString(recordHande, (uint)(i + 1)); char columnTypeIndicator = columnTypeDescriptor[0]; switch (Char.ToLower(columnTypeIndicator)) { case 'i': // Integer case 'j': // Temporary integer columnDefinitions[i].DataType = MsiColumnDataType.Integer; break; case 's': // String case 'g': // Temporary string case 'l': columnDefinitions[i].DataType = MsiColumnDataType.String; break; case 'v': // Binary Stream case 'o': // Undocumented. columnDefinitions[i].DataType = MsiColumnDataType.Binary; break; default: throw new NotImplementedException(string.Format("Unexpected column type: '{0}'.", columnTypeDescriptor)); } } } finally { Msi.CloseHandle(recordHande); } return(columnDefinitions); }
private static DataTable ReadTable(IntPtr databaseHandle, string tableName) { string query = string.Format("SELECT * FROM {0}", tableName); IntPtr viewHandle; Msi.DatabaseOpenView(databaseHandle, query, out viewHandle); try { List <MsiColumnDefinition> columnDefinitions = ReadColumnDefinitions(viewHandle); // Write columns to data table DataTable dataTable = new DataTable(tableName); for (int i = 0; i < columnDefinitions.Count; i++) { Type columnType; switch (columnDefinitions[i].DataType) { case MsiColumnDataType.String: columnType = typeof(string); break; case MsiColumnDataType.Integer: columnType = typeof(int); break; case MsiColumnDataType.Binary: columnType = typeof(byte[]); break; default: throw new NotImplementedException(String.Format("Unexpected column type: '{0}'", columnDefinitions[i].DataType)); } dataTable.Columns.Add(columnDefinitions[i].Name, columnType); } // Read rows IntPtr recordHande = IntPtr.Zero; try { while (Msi.ViewFetch(viewHandle, ref recordHande)) { DataRow dataRow = dataTable.NewRow(); for (int i = 0; i < columnDefinitions.Count; i++) { uint column = (uint)(i + 1); if (Msi.RecordIsNull(recordHande, column)) { dataRow[i] = DBNull.Value; } else if (columnDefinitions[i].DataType == MsiColumnDataType.Integer) { int value = Msi.RecordGetInteger(recordHande, column); dataRow[i] = value; } else if (columnDefinitions[i].DataType == MsiColumnDataType.String) { dataRow[i] = Msi.RecordGetString(recordHande, column); } else if (columnDefinitions[i].DataType == MsiColumnDataType.Binary) { dataRow[i] = Msi.RecordReadStream(recordHande, column); } } dataTable.Rows.Add(dataRow); } } finally { if (recordHande != IntPtr.Zero) { Msi.CloseHandle(recordHande); } } return(dataTable); } finally { Msi.CloseHandle(viewHandle); } }