예제 #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));
            }
        }
예제 #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;
                }
            }
        }
예제 #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);
            }
        }
예제 #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);
        }
예제 #5
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);
        }
예제 #6
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);
        }
예제 #7
0
파일: patches.cs 프로젝트: zooba/wix3
        private DataView GetPatchData(string patchCode)
        {
            DataTable table = new DataTable("PatchProperties");
            table.Locale = CultureInfo.InvariantCulture;
            table.Columns.Add("PatchPropertiesProperty", typeof(string));
            table.Columns.Add("PatchPropertiesValue", typeof(string));

            table.Rows.Add(new object[] { "PatchCode", patchCode });

            PatchInstallation patch = new PatchInstallation(patchCode, null);

            string localPackage = null;
            foreach(string property in new string[]
            {
                "InstallDate",
                "LocalPackage",
                "State",
                "Transforms",
                "Uninstallable",
            })
            {
                try
                {
                    string value = patch[property];
                    table.Rows.Add(new object[] { property,  (value != null ? value : "") });
                    if(property == "LocalPackage") localPackage = value;
                }
                catch(InstallerException iex)
                {
                    table.Rows.Add(new object[] { property, iex.Message });
                }
                catch(ArgumentException) { }
            }

            if(localPackage != null)
            {
                try
                {
                    using(SummaryInfo patchSummaryInfo = new SummaryInfo(localPackage, false))
                    {
                        table.Rows.Add(new object[] { "Title", patchSummaryInfo.Title });
                        table.Rows.Add(new object[] { "Subject", patchSummaryInfo.Subject });
                        table.Rows.Add(new object[] { "Author", patchSummaryInfo.Author });
                        table.Rows.Add(new object[] { "Comments", patchSummaryInfo.Comments });
                        table.Rows.Add(new object[] { "TargetProductCodes", patchSummaryInfo.Template });
                        string obsoletedPatchCodes = patchSummaryInfo.RevisionNumber.Substring(patchSummaryInfo.RevisionNumber.IndexOf('}') + 1);
                        table.Rows.Add(new object[] { "ObsoletedPatchCodes", obsoletedPatchCodes });
                        table.Rows.Add(new object[] { "TransformNames", patchSummaryInfo.LastSavedBy });
                    }
                }
                catch(InstallerException) { }
                catch(IOException) { }
                catch(SecurityException) { }
            }
            return new DataView(table, "", "PatchPropertiesProperty ASC", DataViewRowState.CurrentRows);
        }
예제 #8
0
파일: Database.cs 프로젝트: segilbert/coapp
        /// <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>
        internal 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;
                }
            }
        }
예제 #9
0
파일: Database.cs 프로젝트: segilbert/coapp
 /// <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>
 internal 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);
     }
 }
예제 #10
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)
 {
 }
예제 #11
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;
        }
예제 #12
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);
            }
        }