public IntPtr MsiGetRecordHandle(IntPtr hDatabase, IntPtr hView, int desiredRecordNumber) { int index, rowcount = 0; IntPtr hRecord = IntPtr.Zero; string propertyFieldValue; uint retVal = CwMsiWin32.ERROR_SUCCESS; //string colname; //IntPtr hColNames; //get first record retVal = CwMsiWin32.MsiViewFetch(hView, out hRecord); MsiThrowOnFailure(hDatabase, retVal, "MsiViewFetch"); //loop through all records in this view do { index = 0; Dictionary <int, string> values = new Dictionary <int, string>(); //get all fields in this record while (MsiRecordGetStringW(hRecord, (uint)index, out propertyFieldValue) == CwMsiWin32.ERROR_SUCCESS && propertyFieldValue != "") { //string colname = MsiViewGetColumnInfo(hView, MSICOLINFO_NAMES, hColNames); values[(int)index] = propertyFieldValue; index++; } if (rowcount == desiredRecordNumber) { break; } retVal = CwMsiWin32.MsiViewFetch(hView, out hRecord); rowcount++; }while (retVal != CwMsiWin32.ERROR_NO_MORE_ITEMS); return(hRecord); }
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); }