示例#1
0
        /// <summary>
        /// Executes the query specified by a SQL string.  The query may not be a SELECT statement.
        /// </summary>
        /// <param name="sql">SQL query string</param>
        /// <param name="record">Optional Record object containing the values that replace
        /// the parameter tokens (?) in the SQL query.</param>
        /// <exception cref="BadQuerySyntaxException">the SQL syntax is invalid</exception>
        /// <exception cref="InstallerException">the View could not be executed</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>
        /// </p></remarks>
        internal void Execute(string sql, Record record)
        {
            if (String.IsNullOrEmpty(sql))
            {
                throw new ArgumentNullException("sql");
            }

            using (View view = this.OpenView(sql))
            {
                view.Execute(record);
            }
        }
示例#2
0
 internal void SaveErrorRecord()
 {
     // TODO: pass an affinity handle here?
     int recordHandle = RemotableNativeMethods.MsiGetLastErrorRecord(0);
     if (recordHandle != 0)
     {
         using (Record errorRec = new Record((IntPtr) recordHandle, true, null))
         {
             this.errorData = new object[errorRec.FieldCount];
             for (int i = 0; i < this.errorData.Length; i++)
             {
                 this.errorData[i] = errorRec[i + 1];
             }
         }
     }
     else
     {
         this.errorData = null;
     }
 }
示例#3
0
 internal RecordStream(Record record, int field)
     : base()
 {
     this.record = record;
     this.field = field;
 }
示例#4
0
        private static IList<string> GetTablePrimaryKeys(Database db, string table)
        {
            if (table == "_Tables")
            {
                return new string[] { "Name" };
            }
            else if (table == "_Columns")
            {
                return new string[] { "Table", "Number" };
            }
            else if (table == "_Storages")
            {
                return new string[] { "Name" };
            }
            else if (table == "_Streams")
            {
                return new string[] { "Name" };
            }
            else
            {
                int hrec;
                uint ret = RemotableNativeMethods.MsiDatabaseGetPrimaryKeys(
                    (int) db.Handle, table, out hrec);
                if (ret != 0)
                {
                    throw InstallerException.ExceptionFromReturnCode(ret);
                }

                using (Record rec = new Record((IntPtr) hrec, true, null))
                {
                    string[] keys = new string[rec.FieldCount];
                    for (int i = 0; i < keys.Length; i++)
                    {
                        keys[i] = rec.GetString(i + 1);
                    }

                    return keys;
                }
            }
        }
示例#5
0
文件: Session.cs 项目: virmitio/coapp
        internal MessageResult Message(InstallMessage messageType, Record record)
        {
            if (record == null)
            {
                throw new ArgumentNullException("record");
            }

            int ret = RemotableNativeMethods.MsiProcessMessage((int) this.Handle, (uint) messageType, (int) record.Handle);
            if (ret < 0)
            {
                throw new InstallerException();
            }
            else if (ret == (int) MessageResult.Cancel)
            {
                throw new InstallCanceledException();
            }
            return (MessageResult) ret;
        }
示例#6
0
文件: Session.cs 项目: virmitio/coapp
        /// <summary>
        /// Writes a message to the log, if logging is enabled.
        /// </summary>
        /// <param name="msg">The line to be written to the log</param>
        /// <remarks><p>
        /// Win32 MSI API:
        /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msiprocessmessage.asp">MsiProcessMessage</a>
        /// </p></remarks>
        internal void Log(string msg)
        {
            if (msg == null)
            {
                throw new ArgumentNullException("msg");
            }

            using (Record rec = new Record(0))
            {
                rec.FormatString = msg;
                this.Message(InstallMessage.Info, rec);
            }
        }
示例#7
0
文件: Session.cs 项目: virmitio/coapp
        internal string FormatRecord(Record record, string format)
        {
            if (record == null)
            {
                throw new ArgumentNullException("record");
            }

            return record.ToString(format, this);
        }
示例#8
0
文件: Session.cs 项目: virmitio/coapp
        internal string Format(string format)
        {
            if (format == null)
            {
                throw new ArgumentNullException("format");
            }

            using (Record formatRec = new Record(0))
            {
                formatRec.FormatString = format;
                return formatRec.ToString(this);
            }
        }
示例#9
0
        /// <summary>
        /// [MSI 4.0] Gets the list of files that can be updated by one or more patches.
        /// </summary>
        /// <param name="productCode">ProductCode (GUID) of the product which is
        /// the target of the patches</param>
        /// <param name="patches">list of file paths of one or more patches to be
        /// analyzed</param>
        /// <returns>List of absolute paths of files that can be updated when the
        /// patches are applied on this system.</returns>
        /// <remarks><p>
        /// Win32 MSI API:
        /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msigetpatchfilelist.asp">MsiGetPatchFileList</a>
        /// </p></remarks>
        internal static IList<string> GetPatchFileList(string productCode, IList<string> patches)
        {
            if (String.IsNullOrEmpty(productCode))
            {
                throw new ArgumentNullException("productCode");
            }

            if (patches == null || patches.Count == 0)
            {
                throw new ArgumentNullException("patches");
            }

            StringBuilder patchList = new StringBuilder();
            foreach (string patch in patches)
            {
                if (patch != null)
                {
                    if (patchList.Length != 0)
                    {
                        patchList.Append(';');
                    }

                    patchList.Append(patch);
                }
            }

            if (patchList.Length == 0)
            {
                throw new ArgumentNullException("patches");
            }

            IntPtr phFileRecords;
            uint cFiles;

            uint ret = NativeMethods.MsiGetPatchFileList(
                productCode,
                patchList.ToString(),
                out cFiles,
                out phFileRecords);
            if (ret != 0)
            {
                throw InstallerException.ExceptionFromReturnCode(ret);
            }

            List<string> files = new List<string>();

            for (uint i = 0; i < cFiles; i++)
            {
                int hFileRec = Marshal.ReadInt32(phFileRecords, (int) i);

                using (Record fileRec = new Record(hFileRec, true, null))
                {
                    files.Add(fileRec.GetString(1));
                }
            }

            return files;
        }
示例#10
0
        /// <summary>
        /// Gets a formatted Windows Installer error message in a specified language.
        /// </summary>
        /// <param name="errorRecord">Error record containing the error number in the first field, and
        /// error-specific parameters in the other fields.</param>
        /// <param name="culture">The locale for the message.</param>
        /// <returns>The message string, or null if the error message or locale is not found.</returns>
        /// <remarks><p>
        /// Error numbers greater than 2000 refer to MSI "internal" errors, and are always
        /// returned in English.
        /// </p></remarks>
        internal static string GetErrorMessage(Record errorRecord, CultureInfo culture)
        {
            if (errorRecord == null)
            {
                throw new ArgumentNullException("errorRecord");
            }
            int errorNumber;
            if (errorRecord.FieldCount < 1 || (errorNumber = (int) errorRecord.GetInteger(1)) == 0)
            {
                throw new ArgumentOutOfRangeException("errorRecord");
            }

            string msg = Installer.GetErrorMessage(errorNumber, culture);
            if (msg != null)
            {
                errorRecord.FormatString = msg;
                msg = errorRecord.ToString((IFormatProvider)null);
            }
            return msg;
        }
示例#11
0
 /// <summary>
 /// Gets a formatted Windows Installer error message in the system default language.
 /// </summary>
 /// <param name="errorRecord">Error record containing the error number in the first field, and
 /// error-specific parameters in the other fields.</param>
 /// <returns>The message string, or null if the error message is not found.</returns>
 /// <remarks><p>
 /// Error numbers greater than 2000 refer to MSI "internal" errors, and are always
 /// returned in English.
 /// </p></remarks>
 internal static string GetErrorMessage(Record errorRecord)
 {
     return Installer.GetErrorMessage(errorRecord, null);
 }
示例#12
0
        /// <summary>
        /// Executes the specified SQL SELECT query and returns all results as strings.
        /// </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>All results combined into an array</returns>
        /// <exception cref="BadQuerySyntaxException">the SQL syntax is invalid</exception>
        /// <exception cref="InstallerException">the View could not be executed</exception>
        /// <exception cref="InvalidHandleException">the Database handle is invalid</exception>
        /// <remarks><p>
        /// Multiple rows columns will be collapsed into a single on-dimensional list.
        /// </p><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>
        internal IList<string> ExecuteStringQuery(string sql, Record record)
        {
            if (String.IsNullOrEmpty(sql))
            {
                throw new ArgumentNullException("sql");
            }

            using (View view = this.OpenView(sql))
            {
                view.Execute(record);
                IList<string> results = new List<string>();
                int fieldCount = 0;

                foreach (Record rec in view) using (rec)
                {
                    if (fieldCount == 0) fieldCount = rec.FieldCount;
                    for (int i = 1; i <= fieldCount; i++)
                    {
                        results.Add(rec.GetString(i));
                    }
                }

                return results;
            }
        }
示例#13
0
        /// <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>
        internal 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();
            }
        }