예제 #1
0
        /// <summary>
        /// Reads a record stream field into a file.
        /// </summary>
        /// <param name="field">Specifies the field of the Record to get.</param>
        /// <param name="filePath">Specifies the path to the file to contain the stream.</param>
        /// <exception cref="ArgumentOutOfRangeException">The field is less than 0 or greater than the
        /// number of fields in the Record.</exception>
        /// <exception cref="NotSupportedException">Attempt to extract a storage from a database open
        /// in read-write mode, or from a database without an associated file path</exception>
        /// <remarks><p>
        /// This method is capable of directly extracting substorages. To do so, first select both the
        /// `Name` and `Data` column of the `_Storages` table, then get the stream of the `Data` field.
        /// However, substorages may only be extracted from a database that is open in read-only mode.
        /// </p><p>
        /// Win32 MSI API:
        /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msirecordreadstream.asp">MsiRecordReadStream</a>
        /// </p></remarks>
        public void GetStream(int field, string filePath)
        {
            if (String.IsNullOrEmpty(filePath))
            {
                throw new ArgumentNullException("filePath");
            }

            IList <TableInfo> tables = (this.view != null ? this.view.Tables : null);

            if (tables != null && tables.Count == 1 && tables[0].Name == "_Storages" && field == this.FindColumn("Data"))
            {
                if (!this.view.Database.IsReadOnly)
                {
                    throw new NotSupportedException("Database must be opened read-only to support substorage extraction.");
                }
                else if (this.view.Database.FilePath == null)
                {
                    throw new NotSupportedException("Database must have an associated file path to support substorage extraction.");
                }
                else if (this.FindColumn("Name") <= 0)
                {
                    throw new NotSupportedException("Name column must be part of the Record in order to extract substorage.");
                }
                else
                {
                    Record.ExtractSubStorage(this.view.Database.FilePath, this.GetString("Name"), filePath);
                }
            }
            else
            {
                if (!this.IsNull(field))
                {
                    using (var readStream = new RecordStream(this, field))
                        using (var writeStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
                        {
                            int    count = 512;
                            byte[] buf   = new byte[count];
                            while (count == buf.Length)
                            {
                                if ((count = readStream.Read(buf, 0, buf.Length)) > 0)
                                {
                                    writeStream.Write(buf, 0, count);
                                }
                            }
                        }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Reads a record stream field into a file.
        /// </summary>
        /// <param name="field">Specifies the field of the Record to get.</param>
        /// <param name="filePath">Specifies the path to the file to contain the stream.</param>
        /// <exception cref="ArgumentOutOfRangeException">The field is less than 0 or greater than the
        /// number of fields in the Record.</exception>
        /// <exception cref="NotSupportedException">Attempt to extract a storage from a database open
        /// in read-write mode, or from a database without an associated file path</exception>
        /// <remarks><p>
        /// This method is capable of directly extracting substorages. To do so, first select both the
        /// `Name` and `Data` column of the `_Storages` table, then get the stream of the `Data` field.
        /// However, substorages may only be extracted from a database that is open in read-only mode.
        /// </p><p>
        /// Win32 MSI API:
        /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msirecordreadstream.asp">MsiRecordReadStream</a>
        /// </p></remarks>
        public void GetStream(int field, string filePath)
        {
            if (String.IsNullOrEmpty(filePath))
            {
                throw new ArgumentNullException("filePath");
            }

            IList<TableInfo> tables = (this.view != null ? this.view.Tables : null);
            if (tables != null && tables.Count == 1 && tables[0].Name == "_Storages" && field == this.FindColumn("Data"))
            {
                if (!this.view.Database.IsReadOnly)
                {
                    throw new NotSupportedException("Database must be opened read-only to support substorage extraction.");
                }
                else if (this.view.Database.FilePath == null)
                {
                    throw new NotSupportedException("Database must have an associated file path to support substorage extraction.");
                }
                else if (this.FindColumn("Name") <= 0)
                {
                    throw new NotSupportedException("Name column must be part of the Record in order to extract substorage.");
                }
                else
                {
                    Record.ExtractSubStorage(this.view.Database.FilePath, this.GetString("Name"), filePath);
                }
            }
            else
            {
                if (!this.IsNull(field))
                {
                    Stream readStream = null, writeStream = null;
                    try
                    {
                        readStream = new RecordStream(this, field);
                        writeStream = new FileStream(filePath, FileMode.Create, FileAccess.Write);
                        int count = 512;
                        byte[] buf = new byte[count];
                        while (count == buf.Length)
                        {
                            if ((count = readStream.Read(buf, 0, buf.Length)) > 0)
                            {
                                writeStream.Write(buf, 0, count);
                            }
                        }
                    }
                    finally
                    {
                        if (readStream != null) readStream.Close();
                        if (writeStream != null) writeStream.Close();
                    }
                }
            }
        }