/// <summary> /// Imports all database tables, streams, and summary information from archive files. /// </summary> /// <param name="directoryPath">Path to the directory from which archive files will be imported</param> /// <exception cref="FileNotFoundException">the directory path is invalid</exception> /// <exception cref="InvalidHandleException">the Database handle is invalid</exception> /// <remarks><p> /// Win32 MSI API: /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msidatabaseimport.asp">MsiDatabaseImport</a> /// </p></remarks> public void ImportAll(string directoryPath) { if (String.IsNullOrEmpty(directoryPath)) { throw new ArgumentNullException("directoryPath"); } if (File.Exists(Path.Combine(directoryPath, "_SummaryInformation.idt"))) { this.Import(Path.Combine(directoryPath, "_SummaryInformation.idt")); } string[] idtFiles = Directory.GetFiles(directoryPath, "*.idt"); foreach (string file in idtFiles) { if (Path.GetFileName(file) != "_SummaryInformation.idt") { this.Import(file); } } if (Directory.Exists(Path.Combine(directoryPath, "_Streams"))) { View view = this.OpenView("SELECT `Name`, `Data` FROM `_Streams`"); Record rec = null; try { view.Execute(); string[] streamFiles = Directory.GetFiles(Path.Combine(directoryPath, "_Streams")); foreach (string file in streamFiles) { rec = this.CreateRecord(2); rec[1] = Path.GetFileName(file); rec.SetStream(2, file); view.Insert(rec); rec.Close(); rec = null; } } finally { if (rec != null) { rec.Close(); } view.Close(); } } }
/// <summary> /// Query an MSI table for all records /// </summary> /// <param name="msi">The path to an MSI</param> /// <param name="sql">An MSI query</param> /// <returns>A list of records is returned</returns> /// <remarks>Uses DTF</remarks> public static List <DTF.Record> QueryAllRecords(string msi, string query) { List <DTF.Record> result = new List <DTF.Record>(); using (DTF.Database database = new DTF.Database(msi, DTF.DatabaseOpenMode.ReadOnly)) { using (DTF.View view = database.OpenView(query, null)) { view.Execute(); DTF.Record record = null; while (null != (record = view.Fetch())) { // Copy record created by Fetch to record created manually to remove View reference DTF.Record copyRecord = new DTF.Record(record.FieldCount); for (int i = 0; i <= record.FieldCount; i++) { copyRecord[i] = record[i]; } record.Close(); result.Add(copyRecord); } } } return(result); }
/// <summary> /// Executes the specified SQL SELECT query and returns a single result. /// </summary> /// <param name="sql">SQL SELECT query string</param> /// <param name="record">Optional Record object containing the values that replace /// the parameter tokens (?) in the SQL query.</param> /// <returns>First field of the first result</returns> /// <exception cref="BadQuerySyntaxException">the SQL syntax is invalid</exception> /// <exception cref="InstallerException">the View could not be executed /// or the query returned 0 results</exception> /// <exception cref="InvalidHandleException">the Database handle is invalid</exception> /// <remarks><p> /// Win32 MSI APIs: /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msidatabaseopenview.asp">MsiDatabaseOpenView</a>, /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msiviewexecute.asp">MsiViewExecute</a>, /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msiviewfetch.asp">MsiViewFetch</a> /// </p></remarks> public object ExecuteScalar(string sql, Record record) { if (String.IsNullOrEmpty(sql)) { throw new ArgumentNullException("sql"); } View view = this.OpenView(sql); Record rec = null; try { view.Execute(record); rec = view.Fetch(); if (rec == null) { throw InstallerException.ExceptionFromReturnCode((uint)NativeMethods.Error.NO_MORE_ITEMS); } return(rec[1]); } finally { if (rec != null) { rec.Close(); } view.Close(); } }