Esempio n. 1
0
        /// <summary>
        /// Checks whether a transform is valid for this Database, according to its validation data and flags.
        /// </summary>
        /// <param name="transformFile">Path to the transform file</param>
        /// <returns>true if the transform can be validly applied to this Database; false otherwise</returns>
        /// <exception cref="InstallerException">the transform could not be applied</exception>
        /// <exception cref="InvalidHandleException">the Database handle is invalid</exception>
        public bool IsTransformValid(string transformFile)
        {
            if (String.IsNullOrEmpty(transformFile))
            {
                throw new ArgumentNullException("transformFile");
            }

            using (SummaryInfo transformSummInfo = new SummaryInfo(transformFile, false))
            {
                return(this.IsTransformValid(transformSummInfo));
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Closes the database handle.  After closing a handle, further method calls may throw <see cref="InvalidHandleException"/>.
        /// </summary>
        /// <param name="disposing">If true, the method has been called directly or
        /// indirectly by a user's code, so managed and unmanaged resources will be
        /// disposed. If false, only unmanaged resources will be disposed.</param>
        protected override void Dispose(bool disposing)
        {
            if (!this.IsClosed &&
                (this.OpenMode == DatabaseOpenMode.CreateDirect ||
                 this.OpenMode == DatabaseOpenMode.Direct))
            {
                // Always commit a direct-opened database before closing.
                // This avoids unexpected corruption of the database.
                this.Commit();
            }

            base.Dispose(disposing);

            if (disposing)
            {
                if (this.summaryInfo != null)
                {
                    this.summaryInfo.Close();
                    this.summaryInfo = null;
                }

                if (this.deleteOnClose != null)
                {
                    foreach (string path in this.deleteOnClose)
                    {
                        try
                        {
                            if (Directory.Exists(path))
                            {
                                Directory.Delete(path, true);
                            }
                            else
                            {
                                if (File.Exists(path))
                                {
                                    File.Delete(path);
                                }
                            }
                        }
                        catch (IOException)
                        {
                        }
                        catch (UnauthorizedAccessException)
                        {
                        }
                    }
                    this.deleteOnClose = null;
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Finalizes the persistent form of the database. All persistent data is written
        /// to the writeable database, and no temporary columns or rows are written.
        /// </summary>
        /// <exception cref="InvalidHandleException">the Database handle is invalid</exception>
        /// <remarks><p>
        /// For a database open in <see cref="DatabaseOpenMode.ReadOnly"/> mode, this method has no effect.
        /// </p><p>
        /// For a database open in <see cref="DatabaseOpenMode.CreateDirect" /> or <see cref="DatabaseOpenMode.Direct" />
        /// mode, it is not necessary to call this method because the database will be automatically committed
        /// when it is closed. However this method may be called at any time to persist the current state of tables
        /// loaded into memory.
        /// </p><p>
        /// For a database open in <see cref="DatabaseOpenMode.Create" /> or <see cref="DatabaseOpenMode.Transact" />
        /// mode, no changes will be persisted until this method is called. If the database object is closed without
        /// calling this method, the database file remains unmodified.
        /// </p><p>
        /// Win32 MSI API:
        /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msidatabasecommit.asp">MsiDatabaseCommit</a>
        /// </p></remarks>
        public void Commit()
        {
            if (this.summaryInfo != null && !this.summaryInfo.IsClosed)
            {
                this.summaryInfo.Persist();
                this.summaryInfo.Close();
                this.summaryInfo = null;
            }
            uint ret = NativeMethods.MsiDatabaseCommit((int)this.Handle);

            if (ret != 0)
            {
                throw InstallerException.ExceptionFromReturnCode(ret);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Apply a transform to the database, suppressing any error conditions
        /// specified by the transform's summary information.
        /// </summary>
        /// <param name="transformFile">Path to the transform file</param>
        /// <exception cref="InstallerException">the transform could not be applied</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/msidatabaseapplytransform.asp">MsiDatabaseApplyTransform</a>
        /// </p></remarks>
        public void ApplyTransform(string transformFile)
        {
            if (String.IsNullOrEmpty(transformFile))
            {
                throw new ArgumentNullException("transformFile");
            }

            TransformErrors errorConditionsToSuppress;

            using (SummaryInfo transformSummInfo = new SummaryInfo(transformFile, false))
            {
                int errorConditions = transformSummInfo.CharacterCount & 0xFFFF;
                errorConditionsToSuppress = (TransformErrors)errorConditions;
            }
            this.ApplyTransform(transformFile, errorConditionsToSuppress);
        }
Esempio n. 5
0
        /// <summary>
        /// Checks whether a transform is valid for this Database, according to its SummaryInfo data.
        /// </summary>
        /// <param name="transformSummaryInfo">SummaryInfo data of a transform file</param>
        /// <returns>true if the transform can be validly applied to this Database; false otherwise</returns>
        /// <exception cref="InstallerException">error processing summary info</exception>
        /// <exception cref="InvalidHandleException">the Database or SummaryInfo handle is invalid</exception>
        public bool IsTransformValid(SummaryInfo transformSummaryInfo)
        {
            if (transformSummaryInfo == null)
            {
                throw new ArgumentNullException("transformSummaryInfo");
            }

            string[] rev = transformSummaryInfo.RevisionNumber.Split(new char[] { ';' }, 3);
            string   targetProductCode    = rev[0].Substring(0, 38);
            string   targetProductVersion = rev[0].Substring(38);
            string   upgradeCode          = rev[2];

            string[] templ = transformSummaryInfo.Template.Split(new char[] { ';' }, 2);
            int      targetProductLanguage = 0;

            if (templ.Length >= 2 && templ[1].Length > 0)
            {
                targetProductLanguage = Int32.Parse(templ[1], CultureInfo.InvariantCulture.NumberFormat);
            }

            int flags         = transformSummaryInfo.CharacterCount;
            int validateFlags = flags >> 16;

            string thisProductCode     = this.ExecutePropertyQuery("ProductCode");
            string thisProductVersion  = this.ExecutePropertyQuery("ProductVersion");
            string thisUpgradeCode     = this.ExecutePropertyQuery("UpgradeCode");
            string thisProductLang     = this.ExecutePropertyQuery("ProductLanguage");
            int    thisProductLanguage = 0;

            if (!String.IsNullOrEmpty(thisProductLang))
            {
                thisProductLanguage = Int32.Parse(thisProductLang, CultureInfo.InvariantCulture.NumberFormat);
            }

            if ((validateFlags & (int)TransformValidations.Product) != 0 &&
                thisProductCode != targetProductCode)
            {
                return(false);
            }

            if ((validateFlags & (int)TransformValidations.UpgradeCode) != 0 &&
                thisUpgradeCode != upgradeCode)
            {
                return(false);
            }

            if ((validateFlags & (int)TransformValidations.Language) != 0 &&
                targetProductLanguage != 0 && thisProductLanguage != targetProductLanguage)
            {
                return(false);
            }

            Version thisProductVer   = new Version(thisProductVersion);
            Version targetProductVer = new Version(targetProductVersion);

            if ((validateFlags & (int)TransformValidations.UpdateVersion) != 0)
            {
                if (thisProductVer.Major != targetProductVer.Major)
                {
                    return(false);
                }
                if (thisProductVer.Minor != targetProductVer.Minor)
                {
                    return(false);
                }
                if (thisProductVer.Build != targetProductVer.Build)
                {
                    return(false);
                }
            }
            else if ((validateFlags & (int)TransformValidations.MinorVersion) != 0)
            {
                if (thisProductVer.Major != targetProductVer.Major)
                {
                    return(false);
                }
                if (thisProductVer.Minor != targetProductVer.Minor)
                {
                    return(false);
                }
            }
            else if ((validateFlags & (int)TransformValidations.MajorVersion) != 0)
            {
                if (thisProductVer.Major != targetProductVer.Major)
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 6
0
 /// <summary>
 /// Gets a SummaryInfo object that can be used to examine, update, and add
 /// properties to the summary information stream of a package or transform.
 /// </summary>
 /// <param name="packagePath">Path to the package (database) or transform</param>
 /// <param name="enableWrite">True to reserve resources for writing summary information properties.</param>
 /// <exception cref="FileNotFoundException">the package does not exist or could not be read</exception>
 /// <exception cref="InstallerException">the package is an invalid format</exception>
 /// <remarks><p>
 /// The SummaryInfo object should be <see cref="InstallerHandle.Close"/>d after use.
 /// It is best that the handle be closed manually as soon as it is no longer
 /// needed, as leaving lots of unused handles open can degrade performance.
 /// </p><p>
 /// Win32 MSI API:
 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msigetsummaryinformation.asp">MsiGetSummaryInformation</a>
 /// </p></remarks>
 public SummaryInfo(string packagePath, bool enableWrite)
     : base((IntPtr)SummaryInfo.OpenSummaryInfo(packagePath, enableWrite), true)
 {
 }