private void SetPackageVisibility(Dtf.Database db, ISet <string> msiPropertyNames)
        {
            bool alreadyVisible = !ProcessMsiPackageCommand.HasProperty(db, "ARPSYSTEMCOMPONENT");

            if (alreadyVisible != this.Facade.Package.Visible) // if not already set to the correct visibility.
            {
                // If the authoring specifically added "ARPSYSTEMCOMPONENT", don't do it again.
                if (!msiPropertyNames.Contains("ARPSYSTEMCOMPONENT"))
                {
                    this.AddMsiProperty("ARPSYSTEMCOMPONENT", this.Facade.Package.Visible ? String.Empty : "1");
                }
            }
        }
        private void SetPerMachineAppropriately(Dtf.Database db, string sourcePath)
        {
            if (this.Facade.MsiPackage.ForcePerMachine)
            {
                if (YesNoDefaultType.No == this.Facade.Package.PerMachine)
                {
                    Messaging.Instance.OnMessage(WixWarnings.PerUserButForcingPerMachine(this.Facade.Package.SourceLineNumbers, sourcePath));
                    this.Facade.Package.PerMachine = YesNoDefaultType.Yes; // ensure that we think the package is per-machine.
                }

                // Force ALLUSERS=1 via the MSI command-line.
                this.AddMsiProperty("ALLUSERS", "1");
            }
            else
            {
                string allusers = ProcessMsiPackageCommand.GetProperty(db, "ALLUSERS");

                if (String.IsNullOrEmpty(allusers))
                {
                    // Not forced per-machine and no ALLUSERS property, flip back to per-user.
                    if (YesNoDefaultType.Yes == this.Facade.Package.PerMachine)
                    {
                        Messaging.Instance.OnMessage(WixWarnings.ImplicitlyPerUser(this.Facade.Package.SourceLineNumbers, sourcePath));
                        this.Facade.Package.PerMachine = YesNoDefaultType.No;
                    }
                }
                else if (allusers.Equals("1", StringComparison.Ordinal))
                {
                    if (YesNoDefaultType.No == this.Facade.Package.PerMachine)
                    {
                        Messaging.Instance.OnMessage(WixErrors.PerUserButAllUsersEquals1(this.Facade.Package.SourceLineNumbers, sourcePath));
                    }
                }
                else if (allusers.Equals("2", StringComparison.Ordinal))
                {
                    Messaging.Instance.OnMessage(WixWarnings.DiscouragedAllUsersValue(this.Facade.Package.SourceLineNumbers, sourcePath, (YesNoDefaultType.Yes == this.Facade.Package.PerMachine) ? "machine" : "user"));
                }
                else
                {
                    Messaging.Instance.OnMessage(WixErrors.UnsupportedAllUsersValue(this.Facade.Package.SourceLineNumbers, sourcePath, allusers));
                }
            }
        }
        /// <summary>
        /// Processes the MSI packages to add properties and payloads from the MSI packages.
        /// </summary>
        public void Execute()
        {
            WixBundlePayloadRow packagePayload = this.AuthoredPayloads.Get(this.Facade.Package.PackagePayload);

            string sourcePath       = packagePayload.FullFileName;
            bool   longNamesInImage = false;
            bool   compressed       = false;
            bool   x64 = false;

            try
            {
                // Read data out of the msi database...
                using (Dtf.SummaryInfo sumInfo = new Dtf.SummaryInfo(sourcePath, false))
                {
                    // 1 is the Word Count summary information stream bit that means
                    // the MSI uses short file names when set. We care about long file
                    // names so check when the bit is not set.
                    longNamesInImage = 0 == (sumInfo.WordCount & 1);

                    // 2 is the Word Count summary information stream bit that means
                    // files are compressed in the MSI by default when the bit is set.
                    compressed = 2 == (sumInfo.WordCount & 2);

                    x64 = (sumInfo.Template.Contains("x64") || sumInfo.Template.Contains("Intel64"));

                    // 8 is the Word Count summary information stream bit that means
                    // "Elevated privileges are not required to install this package."
                    // in MSI 4.5 and below, if this bit is 0, elevation is required.
                    this.Facade.Package.PerMachine = (0 == (sumInfo.WordCount & 8)) ? YesNoDefaultType.Yes : YesNoDefaultType.No;
                    this.Facade.Package.x64        = x64 ? YesNoType.Yes : YesNoType.No;
                }

                using (Dtf.Database db = new Dtf.Database(sourcePath))
                {
                    this.Facade.MsiPackage.ProductCode     = ProcessMsiPackageCommand.GetProperty(db, "ProductCode");
                    this.Facade.MsiPackage.UpgradeCode     = ProcessMsiPackageCommand.GetProperty(db, "UpgradeCode");
                    this.Facade.MsiPackage.Manufacturer    = ProcessMsiPackageCommand.GetProperty(db, "Manufacturer");
                    this.Facade.MsiPackage.ProductLanguage = Convert.ToInt32(ProcessMsiPackageCommand.GetProperty(db, "ProductLanguage"), CultureInfo.InvariantCulture);
                    this.Facade.MsiPackage.ProductVersion  = ProcessMsiPackageCommand.GetProperty(db, "ProductVersion");

                    if (!Common.IsValidModuleOrBundleVersion(this.Facade.MsiPackage.ProductVersion))
                    {
                        // not a proper .NET version (e.g., five fields); can we get a valid four-part version number?
                        string   version      = null;
                        string[] versionParts = this.Facade.MsiPackage.ProductVersion.Split('.');
                        int      count        = versionParts.Length;
                        if (0 < count)
                        {
                            version = versionParts[0];
                            for (int i = 1; i < 4 && i < count; ++i)
                            {
                                version = String.Concat(version, ".", versionParts[i]);
                            }
                        }

                        if (!String.IsNullOrEmpty(version) && Common.IsValidModuleOrBundleVersion(version))
                        {
                            Messaging.Instance.OnMessage(WixWarnings.VersionTruncated(this.Facade.Package.SourceLineNumbers, this.Facade.MsiPackage.ProductVersion, sourcePath, version));
                            this.Facade.MsiPackage.ProductVersion = version;
                        }
                        else
                        {
                            Messaging.Instance.OnMessage(WixErrors.InvalidProductVersion(this.Facade.Package.SourceLineNumbers, this.Facade.MsiPackage.ProductVersion, sourcePath));
                        }
                    }

                    if (String.IsNullOrEmpty(this.Facade.Package.CacheId))
                    {
                        this.Facade.Package.CacheId = String.Format("{0}v{1}", this.Facade.MsiPackage.ProductCode, this.Facade.MsiPackage.ProductVersion);
                    }

                    if (String.IsNullOrEmpty(this.Facade.Package.DisplayName))
                    {
                        this.Facade.Package.DisplayName = ProcessMsiPackageCommand.GetProperty(db, "ProductName");
                    }

                    if (String.IsNullOrEmpty(this.Facade.Package.Description))
                    {
                        this.Facade.Package.Description = ProcessMsiPackageCommand.GetProperty(db, "ARPCOMMENTS");
                    }

                    ISet <string> payloadNames = this.GetPayloadTargetNames();

                    ISet <string> msiPropertyNames = this.GetMsiPropertyNames();

                    this.SetPerMachineAppropriately(db, sourcePath);

                    // Ensure the MSI package is appropriately marked visible or not.
                    this.SetPackageVisibility(db, msiPropertyNames);

                    // Unless the MSI or setup code overrides the default, set MSIFASTINSTALL for best performance.
                    if (!msiPropertyNames.Contains("MSIFASTINSTALL") && !ProcessMsiPackageCommand.HasProperty(db, "MSIFASTINSTALL"))
                    {
                        this.AddMsiProperty("MSIFASTINSTALL", "7");
                    }

                    this.CreateRelatedPackages(db);

                    // If feature selection is enabled, represent the Feature table in the manifest.
                    if (this.Facade.MsiPackage.EnableFeatureSelection)
                    {
                        this.CreateMsiFeatures(db);
                    }

                    // Add all external cabinets as package payloads.
                    this.ImportExternalCabinetAsPayloads(db, packagePayload, payloadNames);

                    // Add all external files as package payloads and calculate the total install size as the rollup of
                    // File table's sizes.
                    this.Facade.Package.InstallSize = this.ImportExternalFileAsPayloadsAndReturnInstallSize(db, packagePayload, longNamesInImage, compressed, payloadNames);

                    // Add all dependency providers from the MSI.
                    this.ImportDependencyProviders(db);
                }
            }
            catch (Dtf.InstallerException e)
            {
                Messaging.Instance.OnMessage(WixErrors.UnableToReadPackageInformation(this.Facade.Package.SourceLineNumbers, sourcePath, e.Message));
            }
        }