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