コード例 #1
0
        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);
            }
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        private static void ReadAllTables(DataContext dataContext, string pathToMsiFile)
        {
            IntPtr databaseHandle;
            int    openFlags = Msi.MsiDbPersistMode_ReadOnly;

            if (Path.GetExtension(pathToMsiFile).Equals(".msp", StringComparison.InvariantCultureIgnoreCase))
            {
                openFlags += Msi.MsiDbPersistMode_PatchFile;
            }

            Msi.OpenDatabase(pathToMsiFile, openFlags, out databaseHandle);
            try
            {
                // Read table metadata table.
                DataTable tableDataTable = ReadTable(databaseHandle, "_Tables");
                // NOTE: The metadata table itself is not listed in _Tables.
                dataContext.Tables.Add(tableDataTable);

                foreach (DataRow row in tableDataTable.Rows)
                {
                    string    tableName = (string)row["Name"];
                    DataTable table     = ReadTable(databaseHandle, tableName);
                    dataContext.Tables.Add(table);
                }

                // Add relations as described in the _Validation metadata table.

                DataTableBinding validationTableBinding = (DataTableBinding)dataContext.Tables["_Validation"];
                if (validationTableBinding != null)
                {
                    foreach (DataRow dataRow in validationTableBinding.DataTable.Rows)
                    {
                        if (dataRow.IsNull("KeyTable"))
                        {
                            continue;
                        }

                        string   tableName       = (string)dataRow["Table"];
                        string   columnName      = (string)dataRow["Column"];
                        string[] keyTablesNames  = ((string)dataRow["KeyTable"]).Split(';');
                        int      keyColumnNumber = (int)dataRow["KeyColumn"];

                        foreach (string keyTableName in keyTablesNames)
                        {
                            if (dataContext.Tables[tableName] != null)
                            {
                                TableBinding keyTable = dataContext.Tables[keyTableName];
                                if (keyTable != null && keyColumnNumber >= 1 && keyColumnNumber <= keyTable.Columns.Count)
                                {
                                    string keyColumnName = keyTable.Columns[keyColumnNumber - 1].Name;
                                    dataContext.TableRelations.Add(tableName, new string[] { columnName }, keyTableName, new string[] { keyColumnName });
                                }
                            }
                        }
                    }
                }
            }
            finally
            {
                Msi.CloseHandle(databaseHandle);
            }
        }