Ejemplo n.º 1
0
        public Dictionary <int, Dictionary <string, string> > MsiGetTableRows(IntPtr hDatabase, string tableName)
        {
            Dictionary <int, Dictionary <string, string> > tableRecords = new Dictionary <int, Dictionary <string, string> >();
            Dictionary <string, string> record = new Dictionary <string, string>();
            int    fieldcount = 0;
            uint   retVal     = CwMsiWin32.ERROR_SUCCESS;
            string propertyFieldValue;
            string selectQuery = "SELECT * FROM `" + tableName + "`";
            int    recordCount = 0;
            IntPtr hView       = IntPtr.Zero;
            IntPtr hRecord     = IntPtr.Zero;
            IntPtr hColnames   = IntPtr.Zero;

            retVal = CwMsiWin32.MsiDatabaseOpenViewW(hDatabase, selectQuery, out hView);
            //if we get bad syntax here, just keep going b/c it could just be an invalid table name..?
            if (retVal != CwMsiWin32.ERROR_BAD_QUERY_SYNTAX && retVal != CwMsiWin32.ERROR_SUCCESS)
            {
                MsiThrowOnFailure(hDatabase, retVal, "MsiDatabaseOpenViewW()");
            }
            if (retVal == CwMsiWin32.ERROR_BAD_QUERY_SYNTAX)
            {
                return(null);
            }

            retVal = CwMsiWin32.MsiViewExecute(hView, IntPtr.Zero);
            MsiThrowOnFailure(hDatabase, retVal, "MsiViewExecute()");

            // Loop through the properties and copy the ones passed in to this function
            do
            {
                //clear the record var
                record = new Dictionary <string, string>();

                //fetch the view
                retVal = CwMsiWin32.MsiViewFetch(hView, out hRecord);
                if (retVal != CwMsiWin32.ERROR_SUCCESS && retVal != CwMsiWin32.ERROR_NO_MORE_ITEMS)
                {
                    MsiThrowOnFailure(hDatabase, retVal, "MsiViewFetch");
                }
                if (retVal == CwMsiWin32.ERROR_NO_MORE_ITEMS)
                {
                    break;
                }

                //get the field count
                fieldcount = (int)CwMsiWin32.MsiRecordGetFieldCount(hRecord) + 1; //must add 1 b/c it ignores column 0..?!

                //get the column names
                retVal = CwMsiWin32.MsiViewGetColumnInfo(hView, CwMsiWin32.MSICOLINFO_NAMES, out hColnames);
                MsiThrowOnFailure(hDatabase, retVal, "MsiViewGetColumnInfo");
                string [] colnames = new string[fieldcount];

                //loop the number of times there are fields and get a column name for each
                for (int i = 0; i < fieldcount; i++)
                {
                    string thisColName = "";
                    MsiRecordGetStringW(hColnames, (uint)i, out thisColName);
                    if (thisColName == "" && i == 0) //primary key is 0
                    {
                        thisColName = "Primary Key";
                    }
                    else if (thisColName == "")
                    {
                        thisColName = "[unknown]";
                    }
                    colnames[i] = thisColName;
                }

                //loop through all fields, get the column name, and store in our dictionary
                for (int i = 0; i < fieldcount; i++)
                {
                    retVal = MsiRecordGetStringW(hRecord, (uint)i, out propertyFieldValue);
                    MsiThrowOnFailure(hDatabase, retVal, "MsiRecordGetStringW(hRecord," + i.ToString() + "," + propertyFieldValue + ")");
                    record[colnames[i]] = propertyFieldValue;
                }

                //save the record in our table of records
                tableRecords[recordCount] = record;

                retVal = CwMsiWin32.MsiCloseHandle(hRecord);
                MsiThrowOnFailure(hDatabase, retVal, "MsiCloseHandle(hRecord)");
                recordCount++;
            }while (retVal != CwMsiWin32.ERROR_NO_MORE_ITEMS);

            retVal = CwMsiWin32.MsiCloseHandle(hView);
            MsiThrowOnFailure(hDatabase, retVal, "MsiCloseHandle");

            return(tableRecords);
        }
Ejemplo n.º 2
0
        public void MsiCreateEditRecordInTable(IntPtr hDatabase, string tableName, string action, int recordnumber, int[] fieldnumbers, ArrayList fieldvalues)
        {
            uint retVal    = CwMsiWin32.ERROR_SUCCESS;
            int  numfields = fieldvalues.Count;
            int  msiAction = -1;

            //create a view to be used later for the operation
            IntPtr hView = IntPtr.Zero;
            string q     = "SELECT * FROM `" + tableName + "`";

            retVal = CwMsiWin32.MsiDatabaseOpenViewW(hDatabase, q, out hView);
            MsiThrowOnFailure(hDatabase, retVal, "MsiDatabaseOpenViewW('" + q + "')");

            //execute the view
            retVal = CwMsiWin32.MsiViewExecute(hView, IntPtr.Zero);
            MsiThrowOnFailure(hDatabase, retVal, "MsiViewExecute()");

            IntPtr hRecord = (IntPtr)(0);

            //create a record ptr with numfields
            if (action == "CreateRecord")
            {
                hRecord   = CwMsiWin32.MsiCreateRecord((uint)numfields);
                msiAction = CwMsiWin32.MSIMODIFY_INSERT;

                if (hRecord == IntPtr.Zero)
                {
                    throw new Exception("MsiCreateRecord");
                }

                int fieldnum = 1;  //note:  not a zero-based index!

                //loop through each field in this record and set it
                foreach (object val in fieldvalues)
                {
                    if (val.GetType() == typeof(string))
                    {
                        retVal = CwMsiWin32.MsiRecordSetStringW(hRecord, (uint)fieldnum, (string)val);
                    }
                    else if (val.GetType() == typeof(Int32))
                    {
                        retVal = CwMsiWin32.MsiRecordSetInteger(hRecord, (uint)fieldnum, (Int32)val);
                    }
                    else if (val.GetType() == typeof(Int16))
                    {
                        retVal = CwMsiWin32.MsiRecordSetInteger(hRecord, (uint)fieldnum, (Int16)val);
                    }

                    MsiThrowOnFailure(hDatabase, retVal, "MsiRecordSetStringW(" + fieldnum.ToString() + ", '" + val + "')");
                    fieldnum++;
                }
            }
            else if (action == "ChangeFieldsInRecord")
            {
                //make sure the fieldnumbers size and fieldvalues size match
                if (fieldnumbers.Length != fieldvalues.Count)
                {
                    retVal = CwMsiWin32.MsiCloseHandle(hView);
                    MsiThrowOnFailure(hDatabase, retVal, "MsiCloseHandle(hView)");
                    throw new Exception("fieldnumbers and fieldvalues are not equal.");
                }

                hRecord = MsiGetRecordHandle(hDatabase, hView, recordnumber);
                int i = 0;
                //loop through all field numbers we want to change in this record
                //and alter those fields in the record we just retrieved
                foreach (int fieldnum in fieldnumbers)
                {
                    retVal = CwMsiWin32.MsiRecordSetStringW(hRecord, (uint)fieldnum, fieldvalues[i].ToString());
                    MsiThrowOnFailure(hDatabase, retVal, "MsiRecordSetStringW(hRecord," + fieldnum.ToString() + "," + fieldvalues[i] + ")");
                    i++;
                }

                msiAction = CwMsiWin32.MSIMODIFY_UPDATE;
            }
            else
            {
                retVal = CwMsiWin32.MsiCloseHandle(hView);
                MsiThrowOnFailure(hDatabase, retVal, "MsiCloseHandle(hView)");
                throw new Exception("Error:  Invalid action specified '" + msiAction + "'!");
            }

            if (hRecord == (IntPtr)(-1))
            {
                throw new Exception("Failed to retrieve hRecord!");
            }

            //perform the operation on the MSI database
            retVal = CwMsiWin32.MsiViewModify(hView, msiAction, hRecord);
            MsiThrowOnFailure(hDatabase, retVal, "MsiViewModify - failed to alter/create record");

            //cleanup
            retVal = CwMsiWin32.MsiCloseHandle(hRecord);
            MsiThrowOnFailure(hDatabase, retVal, "MsiCloseHandle(hRecord)");
            retVal = CwMsiWin32.MsiCloseHandle(hView);
            MsiThrowOnFailure(hDatabase, retVal, "MsiCloseHandle(hView)");
            retVal = CwMsiWin32.MsiDatabaseCommit(hDatabase);
            MsiThrowOnFailure(hDatabase, retVal, "MsiDatabaseCommit(hDatabase)");
        }
Ejemplo n.º 3
0
        public void MsiCreateRecordFromMsiTable(IntPtr hDatabase, string tableName, object tableStruct, int numfields)
        {
            uint   retVal   = CwMsiWin32.ERROR_SUCCESS;
            IntPtr hView    = IntPtr.Zero;
            string q        = "SELECT * FROM `" + tableName + "`";
            IntPtr hRecord  = (IntPtr)(0);
            int    fieldnum = 1;

            //create a view to be used later for the operation
            retVal = CwMsiWin32.MsiDatabaseOpenViewW(hDatabase, q, out hView);
            MsiThrowOnFailure(hDatabase, retVal, "MsiDatabaseOpenViewW('" + q + "')");

            //execute the view
            retVal = CwMsiWin32.MsiViewExecute(hView, IntPtr.Zero);
            MsiThrowOnFailure(hDatabase, retVal, "MsiViewExecute()");

            //create the record
            hRecord = CwMsiWin32.MsiCreateRecord((uint)numfields);

            if (hRecord == IntPtr.Zero)
            {
                throw new Exception("MsiCreateRecord");
            }

            //get the fields for this table - note we can't use [type].GetType().GetFields()
            //because this function returns the fields in an unpredictable order!
            string[] fields = MsiTableGetFieldNames(tableName);

            if (fields == null)
            {
                throw new Exception("No fields for table '" + tableName + "'.");
            }
            if (fields.Length != numfields)
            {
                throw new Exception("Field count mismatch:  fields.Length=" + fields.Length.ToString() + " / numfields=" + numfields.ToString());
            }

            foreach (string thisfield in fields)
            {
                FieldInfo fi    = tableStruct.GetType().GetField(thisfield);
                object    value = fi.GetValue(tableStruct);

                if (value.GetType() == typeof(string))
                {
                    retVal = CwMsiWin32.MsiRecordSetStringW(hRecord, (uint)fieldnum, (string)value);
                }
                else if (value.GetType() == typeof(int))
                {
                    retVal = CwMsiWin32.MsiRecordSetInteger(hRecord, (uint)fieldnum, (int)value);
                }
                else if (value.GetType() == typeof(Int16))
                {
                    retVal = CwMsiWin32.MsiRecordSetInteger(hRecord, (uint)fieldnum, (Int16)value);
                }

                MsiThrowOnFailure(hDatabase, retVal, "MsiRecordSetStringW(" + fieldnum.ToString() + ", '" + value.ToString() + "')");
                fieldnum++;
            }

            //perform the operation on the MSI database
            retVal = CwMsiWin32.MsiViewModify(hView, CwMsiWin32.MSIMODIFY_INSERT, hRecord);
            MsiThrowOnFailure(hDatabase, retVal, "MsiViewModify - failed to alter/create record");

            //cleanup
            retVal = CwMsiWin32.MsiCloseHandle(hRecord);
            MsiThrowOnFailure(hDatabase, retVal, "MsiCloseHandle(hRecord)");
            retVal = CwMsiWin32.MsiCloseHandle(hView);
            MsiThrowOnFailure(hDatabase, retVal, "MsiCloseHandle(hView)");
            retVal = CwMsiWin32.MsiDatabaseCommit(hDatabase);
            MsiThrowOnFailure(hDatabase, retVal, "MsiDatabaseCommit(hDatabase)");
        }