Exemple #1
0
 /// <summary>
 /// Creates a binder.
 /// </summary>
 public WixBinder()
 {
     this.extensions                    = new List <BinderExtension>();
     this.inspectorExtensions           = new List <InspectorExtension>();
     this.fileManager                   = new BinderFileManager();
     this.fileManager.TempFilesLocation = this.TempFilesLocation;
 }
Exemple #2
0
        /// <summary>
        /// Saves an output to a path on disk.
        /// </summary>
        /// <param name="path">Path to save output file to on disk.</param>
        /// <param name="binderFileManager">If provided, the binder file manager is used to bind files into the output.</param>
        /// <param name="wixVariableResolver">The Wix variable resolver.</param>
        /// <param name="tempFilesLocation">Location for temporary files.</param>
        public void Save(string path, BinderFileManager binderFileManager, WixVariableResolver wixVariableResolver, string tempFilesLocation)
        {
            FileMode fileMode = FileMode.Create;

            // Assure the location to output the xml exists
            Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path)));

            // Check if there was a cab on the output when it was created
            if (SaveCab(path, binderFileManager, wixVariableResolver, tempFilesLocation))
            {
                fileMode = FileMode.Append;
            }

            // save the xml
            using (FileStream fs = new FileStream(path, fileMode))
            {
                XmlWriter writer = null;

                try
                {
                    writer = new XmlTextWriter(fs, System.Text.Encoding.UTF8);

                    writer.WriteStartDocument();
                    this.Persist(writer);
                    writer.WriteEndDocument();
                }
                finally
                {
                    if (null != writer)
                    {
                        writer.Close();
                    }
                }
            }
        }
Exemple #3
0
 /// <summary>
 /// Creates a binder.
 /// </summary>
 public WixBinder()
 {
     this.extensions = new List<BinderExtension>();
     this.inspectorExtensions = new List<InspectorExtension>();
     this.fileManager = new BinderFileManager();
     this.fileManager.TempFilesLocation = this.TempFilesLocation;
 }
 /// <summary>
 /// Instantiate a new CabinetWorkItem.
 /// </summary>
 /// <param name="fileRows">The collection of files in this cabinet.</param>
 /// <param name="cabinetFile">The cabinet file.</param>
 /// <param name="maxThreshold">Maximum threshold for each cabinet.</param>
 /// <param name="compressionLevel">The compression level of the cabinet.</param>
 /// <param name="binderFileManager">The binder file manager.</param>
 public CabinetWorkItem(FileRowCollection fileRows, string cabinetFile, int maxThreshold, Cab.CompressionLevel compressionLevel, BinderFileManager binderFileManager)
 {
     this.cabinetFile       = cabinetFile;
     this.compressionLevel  = compressionLevel;
     this.fileRows          = fileRows;
     this.binderFileManager = binderFileManager;
     this.maxThreshold      = maxThreshold;
 }
Exemple #5
0
 /// <summary>
 /// Instantiate a new CabinetWorkItem.
 /// </summary>
 /// <param name="fileRows">The collection of files in this cabinet.</param>
 /// <param name="cabinetFile">The cabinet file.</param>
 /// <param name="maxThreshold">Maximum threshold for each cabinet.</param>
 /// <param name="compressionLevel">The compression level of the cabinet.</param>
 /// <param name="binderFileManager">The binder file manager.</param>
 public CabinetWorkItem(FileRowCollection fileRows, string cabinetFile, int maxThreshold, Cab.CompressionLevel compressionLevel, BinderFileManager binderFileManager)
 {
     this.cabinetFile = cabinetFile;
     this.compressionLevel = compressionLevel;
     this.fileRows = fileRows;
     this.binderFileManager = binderFileManager;
     this.maxThreshold = maxThreshold;
 }
Exemple #6
0
 public ContainerInfo(string id, string name, string type, string downloadUrl, BinderFileManager fileManager)
 {
     this.Id = id;
     this.Name = name;
     this.Type = type;
     this.DownloadUrl = downloadUrl;
     this.FileManager = fileManager;
     this.TempPath = Path.Combine(fileManager.TempFilesLocation, name);
     this.FileInfo = new FileInfo(this.TempPath);
 }
Exemple #7
0
        /// <summary>
        /// Initializes package state from the MSI contents.
        /// </summary>
        private void ResolveMsiPackage(BinderFileManager fileManager, Dictionary<string, PayloadInfoRow> allPayloads, Dictionary<string, ContainerInfo> containers, YesNoType suppressLooseFilePayloadGeneration, YesNoType enableFeatureSelection, YesNoType forcePerMachine, Output bundle)
        {
            string sourcePath = this.PackagePayload.FullFileName;
            bool longNamesInImage = false;
            bool compressed = false;
            try
            {
                // Read data out of the msi database...
                using (Microsoft.Deployment.WindowsInstaller.SummaryInfo sumInfo = new Microsoft.Deployment.WindowsInstaller.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);

                    // 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.PerMachine = (0 == (sumInfo.WordCount & 8)) ? YesNoDefaultType.Yes : YesNoDefaultType.No;
                }

                using (Microsoft.Deployment.WindowsInstaller.Database db = new Microsoft.Deployment.WindowsInstaller.Database(sourcePath))
                {
                    this.ProductCode = ChainPackageInfo.GetProperty(db, "ProductCode");
                    this.Language = ChainPackageInfo.GetProperty(db, "ProductLanguage");
                    this.Version = ChainPackageInfo.GetProperty(db, "ProductVersion");

                    if (!Common.IsValidModuleOrBundleVersion(this.Version))
                    {
                        // not a proper .NET version (i.e., five fields); can we get a valid version number up to four fields?
                        string version = null;
                        string[] versionParts = this.Version.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))
                        {
                            this.core.OnMessage(WixWarnings.VersionTruncated(this.PackagePayload.SourceLineNumbers, this.Version, sourcePath, version));
                            this.Version = version;
                        }
                        else
                        {
                            this.core.OnMessage(WixErrors.InvalidProductVersion(this.PackagePayload.SourceLineNumbers, this.Version, sourcePath));
                        }
                    }

                    if (String.IsNullOrEmpty(this.CacheId))
                    {
                        this.CacheId = String.Format("{0}v{1}", this.ProductCode, this.Version);
                    }

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

                    this.Manufacturer = ChainPackageInfo.GetProperty(db, "Manufacturer");

                    this.VerifyMsiProperties();

                    if (YesNoType.Yes == forcePerMachine)
                    {
                        if (YesNoDefaultType.No == this.PerMachine)
                        {
                            this.core.OnMessage(WixWarnings.PerUserButForcingPerMachine(this.PackagePayload.SourceLineNumbers, sourcePath));
                            this.PerMachine = YesNoDefaultType.Yes; // ensure that we think the MSI is per-machine.
                        }

                        this.MsiProperties.Add(new MsiPropertyInfo(this.Id, "ALLUSERS", "1")); // force ALLUSERS=1 via the MSI command-line.
                    }
                    else if (ChainPackageInfo.HasProperty(db, "ALLUSERS"))
                    {
                        string allusers = ChainPackageInfo.GetProperty(db, "ALLUSERS");
                        if (allusers.Equals("1", StringComparison.Ordinal))
                        {
                            if (YesNoDefaultType.No == this.PerMachine)
                            {
                                this.core.OnMessage(WixErrors.PerUserButAllUsersEquals1(this.PackagePayload.SourceLineNumbers, sourcePath));
                            }
                        }
                        else if (allusers.Equals("2", StringComparison.Ordinal))
                        {
                            this.core.OnMessage(WixWarnings.DiscouragedAllUsersValue(this.PackagePayload.SourceLineNumbers, sourcePath, (YesNoDefaultType.Yes == this.PerMachine) ? "machine" : "user"));
                        }
                        else
                        {
                            this.core.OnMessage(WixErrors.UnsupportedAllUsersValue(this.PackagePayload.SourceLineNumbers, sourcePath, allusers));
                        }
                    }
                    else if (YesNoDefaultType.Yes == this.PerMachine) // not forced per-machine and no ALLUSERS property, flip back to per-user
                    {
                        this.core.OnMessage(WixWarnings.ImplicitlyPerUser(this.PackagePayload.SourceLineNumbers, sourcePath));
                        this.PerMachine = YesNoDefaultType.No;
                    }

                    if (String.IsNullOrEmpty(this.Description) && ChainPackageInfo.HasProperty(db, "ARPCOMMENTS"))
                    {
                        this.Description = ChainPackageInfo.GetProperty(db, "ARPCOMMENTS");
                    }

                    // Ensure the MSI package is appropriately marked visible or not.
                    bool alreadyVisible = !ChainPackageInfo.HasProperty(db, "ARPSYSTEMCOMPONENT");
                    if (alreadyVisible != this.Visible) // if not already set to the correct visibility.
                    {
                        // If the authoring specifically added "ARPSYSTEMCOMPONENT", don't do it again.
                        bool sysComponentSet = false;
                        foreach (MsiPropertyInfo propertyInfo in this.MsiProperties)
                        {
                            if ("ARPSYSTEMCOMPONENT".Equals(propertyInfo.Name, StringComparison.Ordinal))
                            {
                                sysComponentSet = true;
                                break;
                            }
                        }

                        if (!sysComponentSet)
                        {
                            this.MsiProperties.Add(new MsiPropertyInfo(this.Id, "ARPSYSTEMCOMPONENT", this.Visible ? "" : "1"));
                        }
                    }

                    // Unless the MSI or setup code overrides the default, set MSIFASTINSTALL for best performance.
                    if (!ChainPackageInfo.HasProperty(db, "MSIFASTINSTALL"))
                    {
                        bool fastInstallSet = false;
                        foreach (MsiPropertyInfo propertyInfo in this.MsiProperties)
                        {
                            if ("MSIFASTINSTALL".Equals(propertyInfo.Name, StringComparison.Ordinal))
                            {
                                fastInstallSet = true;
                                break;
                            }
                        }

                        if (!fastInstallSet)
                        {
                            this.MsiProperties.Add(new MsiPropertyInfo(this.Id, "MSIFASTINSTALL", "7"));
                        }
                    }

                    this.UpgradeCode = ChainPackageInfo.GetProperty(db, "UpgradeCode");

                        // Represent the Upgrade table as related packages.
                    if (db.Tables.Contains("Upgrade") && !String.IsNullOrEmpty(this.UpgradeCode))
                    {
                        using (Microsoft.Deployment.WindowsInstaller.View view = db.OpenView("SELECT `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes` FROM `Upgrade`"))
                        {
                            view.Execute();
                            while (true)
                            {
                                using (Microsoft.Deployment.WindowsInstaller.Record record = view.Fetch())
                                {
                                    if (null == record)
                                    {
                                        break;
                                    }

                                    RelatedPackage related = new RelatedPackage();
                                    related.Id = record.GetString(1);
                                    related.MinVersion = record.GetString(2);
                                    related.MaxVersion = record.GetString(3);

                                    string languages = record.GetString(4);
                                    if (!String.IsNullOrEmpty(languages))
                                    {
                                        string[] splitLanguages = languages.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                                        related.Languages.AddRange(splitLanguages);
                                    }

                                    int attributes = record.GetInteger(5);
                                    // when an Upgrade row has an upgrade code different than this package's upgrade code, don't count it as a possible downgrade to this package
                                    related.OnlyDetect = ((attributes & MsiInterop.MsidbUpgradeAttributesOnlyDetect) == MsiInterop.MsidbUpgradeAttributesOnlyDetect) && this.UpgradeCode.Equals(related.Id, StringComparison.OrdinalIgnoreCase);
                                    related.MinInclusive = (attributes & MsiInterop.MsidbUpgradeAttributesVersionMinInclusive) == MsiInterop.MsidbUpgradeAttributesVersionMinInclusive;
                                    related.MaxInclusive = (attributes & MsiInterop.MsidbUpgradeAttributesVersionMaxInclusive) == MsiInterop.MsidbUpgradeAttributesVersionMaxInclusive;
                                    related.LangInclusive = (attributes & MsiInterop.MsidbUpgradeAttributesLanguagesExclusive) == 0;

                                    this.RelatedPackages.Add(related);
                                }
                            }
                        }
                    }

                    // If feature selection is enabled, represent the Feature table in the manifest.
                    if (YesNoType.Yes == enableFeatureSelection && db.Tables.Contains("Feature"))
                    {
                        using (Microsoft.Deployment.WindowsInstaller.View featureView = db.OpenView("SELECT `Component_` FROM `FeatureComponents` WHERE `Feature_` = ?"),
                                    componentView = db.OpenView("SELECT `FileSize` FROM `File` WHERE `Component_` = ?"))
                        {
                            using (Microsoft.Deployment.WindowsInstaller.Record featureRecord = new Microsoft.Deployment.WindowsInstaller.Record(1),
                                          componentRecord = new Microsoft.Deployment.WindowsInstaller.Record(1))
                            {
                                using (Microsoft.Deployment.WindowsInstaller.View allFeaturesView = db.OpenView("SELECT * FROM `Feature`"))
                                {
                                    allFeaturesView.Execute();

                                    while (true)
                                    {
                                        using (Microsoft.Deployment.WindowsInstaller.Record allFeaturesResultRecord = allFeaturesView.Fetch())
                                        {
                                            if (null == allFeaturesResultRecord)
                                            {
                                                break;
                                            }

                                            MsiFeature feature = new MsiFeature();
                                            string featureName = allFeaturesResultRecord.GetString(1);
                                            feature.Name = featureName;
                                            feature.Size = 0;
                                            feature.Parent = allFeaturesResultRecord.GetString(2);
                                            feature.Title = allFeaturesResultRecord.GetString(3);
                                            feature.Description = allFeaturesResultRecord.GetString(4);
                                            feature.Display = allFeaturesResultRecord.GetInteger(5);
                                            feature.Level = allFeaturesResultRecord.GetInteger(6);
                                            feature.Directory = allFeaturesResultRecord.GetString(7);
                                            feature.Attributes = allFeaturesResultRecord.GetInteger(8);
                                            this.MsiFeatures.Add(feature);

                                            // Determine Feature Size
                                            featureRecord.SetString(1, featureName);
                                            featureView.Execute(featureRecord);

                                            // Loop over all the components
                                            while (true)
                                            {
                                                using (Microsoft.Deployment.WindowsInstaller.Record componentResultRecord = featureView.Fetch())
                                                {
                                                    if (null == componentResultRecord)
                                                    {
                                                        break;
                                                    }
                                                    string component = componentResultRecord.GetString(1);
                                                    componentRecord.SetString(1, component);
                                                    componentView.Execute(componentRecord);

                                                    // Loop over all the files

                                                    while (true)
                                                    {
                                                        using (Microsoft.Deployment.WindowsInstaller.Record fileResultRecord = componentView.Fetch())
                                                        {
                                                            if (null == fileResultRecord)
                                                            {
                                                                break;
                                                            }

                                                            string fileSize = fileResultRecord.GetString(1);
                                                            feature.Size += Convert.ToInt32(fileSize, CultureInfo.InvariantCulture.NumberFormat);
                                                        }
                                                    }

                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    // Add all external cabinets as package payloads.
                    if (db.Tables.Contains("Media"))
                    {
                        foreach (string cabinet in db.ExecuteStringQuery("SELECT `Cabinet` FROM `Media`"))
                        {
                            if (!String.IsNullOrEmpty(cabinet) && !cabinet.StartsWith("#", StringComparison.Ordinal))
                            {
                                // If we didn't find the Payload as an existing child of the package, we need to
                                // add it.  We expect the file to exist on-disk in the same relative location as
                                // the MSI expects to find it...
                                string cabinetName = Path.Combine(Path.GetDirectoryName(this.PackagePayload.Name), cabinet);
                                if (!this.IsExistingPayload(cabinetName))
                                {
                                    string generatedId = Common.GenerateIdentifier("cab", true, this.PackagePayload.Id, cabinet);
                                    string payloadSourceFile = fileManager.ResolveRelatedFile(this.PackagePayload.UnresolvedSourceFile, cabinet, "Cabinet", this.PackagePayload.SourceLineNumbers, BindStage.Normal);

                                    PayloadInfoRow payloadNew = PayloadInfoRow.Create(this.SourceLineNumbers, bundle, generatedId, cabinetName, payloadSourceFile, true, this.PackagePayload.SuppressSignatureValidation, null, this.PackagePayload.Container, this.PackagePayload.Packaging);
                                    payloadNew.ParentPackagePayload = this.PackagePayload.Id;
                                    if (!String.IsNullOrEmpty(payloadNew.Container))
                                    {
                                        containers[payloadNew.Container].Payloads.Add(payloadNew);
                                    }

                                    this.Payloads.Add(payloadNew);
                                    allPayloads.Add(payloadNew.Id, payloadNew);

                                    this.Size += payloadNew.FileSize; // add the newly added payload to the package size.
                                }
                            }
                        }
                    }

                    // Add all external files as package payloads and calculate the total install size as the rollup of
                    // File table's sizes.
                    this.InstallSize = 0;
                    if (db.Tables.Contains("Component") && db.Tables.Contains("Directory") && db.Tables.Contains("File"))
                    {
                        Hashtable directories = new Hashtable();

                        // Load up the directory hash table so we will be able to resolve source paths
                        // for files in the MSI database.
                        using (Microsoft.Deployment.WindowsInstaller.View view = db.OpenView("SELECT `Directory`, `Directory_Parent`, `DefaultDir` FROM `Directory`"))
                        {
                            view.Execute();
                            while (true)
                            {
                                using (Microsoft.Deployment.WindowsInstaller.Record record = view.Fetch())
                                {
                                    if (null == record)
                                    {
                                        break;
                                    }
                                    string sourceName = Installer.GetName(record.GetString(3), true, longNamesInImage);
                                    directories.Add(record.GetString(1), new ResolvedDirectory(record.GetString(2), sourceName));
                                }
                            }
                        }

                        // Resolve the source paths to external files and add each file size to the total
                        // install size of the package.
                        using (Microsoft.Deployment.WindowsInstaller.View view = db.OpenView("SELECT `Directory_`, `File`, `FileName`, `File`.`Attributes`, `FileSize` FROM `Component`, `File` WHERE `Component`.`Component`=`File`.`Component_`"))
                        {
                            view.Execute();
                            while (true)
                            {
                                using (Microsoft.Deployment.WindowsInstaller.Record record = view.Fetch())
                                {
                                    if (null == record)
                                    {
                                        break;
                                    }

                                    // Skip adding the loose files as payloads if it was suppressed.
                                    if (suppressLooseFilePayloadGeneration != YesNoType.Yes)
                                    {
                                        // If the file is explicitly uncompressed or the MSI is uncompressed and the file is not
                                        // explicitly marked compressed then this is an external file.
                                        if (MsiInterop.MsidbFileAttributesNoncompressed == (record.GetInteger(4) & MsiInterop.MsidbFileAttributesNoncompressed) ||
                                            (!compressed && 0 == (record.GetInteger(4) & MsiInterop.MsidbFileAttributesCompressed)))
                                        {
                                            string generatedId = Common.GenerateIdentifier("f", true, this.PackagePayload.Id, record.GetString(2));
                                            string fileSourcePath = Binder.GetFileSourcePath(directories, record.GetString(1), record.GetString(3), compressed, longNamesInImage);
                                            string payloadSourceFile = fileManager.ResolveRelatedFile(this.PackagePayload.UnresolvedSourceFile, fileSourcePath, "File", this.PackagePayload.SourceLineNumbers, BindStage.Normal);
                                            string name = Path.Combine(Path.GetDirectoryName(this.PackagePayload.Name), fileSourcePath);

                                            if (!this.IsExistingPayload(name))
                                            {
                                                PayloadInfoRow payloadNew = PayloadInfoRow.Create(this.SourceLineNumbers, bundle, generatedId, name, payloadSourceFile, true, this.PackagePayload.SuppressSignatureValidation, null, this.PackagePayload.Container, this.PackagePayload.Packaging);
                                                payloadNew.ParentPackagePayload = this.PackagePayload.Id;
                                                if (!String.IsNullOrEmpty(payloadNew.Container))
                                                {
                                                    containers[payloadNew.Container].Payloads.Add(payloadNew);
                                                }

                                                this.Payloads.Add(payloadNew);
                                                allPayloads.Add(payloadNew.Id, payloadNew);

                                                this.Size += payloadNew.FileSize; // add the newly added payload to the package size.
                                            }
                                        }
                                    }

                                    this.InstallSize += record.GetInteger(5);
                                }
                            }
                        }
                    }

                    // Import any dependency providers from the MSI.
                    if (db.Tables.Contains("WixDependencyProvider"))
                    {
                        // Use the old schema (v1) if the Version column does not exist.
                        bool hasVersion = db.Tables["WixDependencyProvider"].Columns.Contains("Version");
                        string query = "SELECT `ProviderKey`, `Version`, `DisplayName`, `Attributes` FROM `WixDependencyProvider`";

                        if (!hasVersion)
                        {
                            query = "SELECT `ProviderKey`, `Attributes` FROM `WixDependencyProvider`";
                        }

                        using (Microsoft.Deployment.WindowsInstaller.View view = db.OpenView(query))
                        {
                            view.Execute();
                            while (true)
                            {
                                using (Microsoft.Deployment.WindowsInstaller.Record record = view.Fetch())
                                {
                                    if (null == record)
                                    {
                                        break;
                                    }

                                    // Import the provider key and attributes.
                                    ProvidesDependency dependency = null;
                                    string providerKey = record.GetString(1);

                                    if (hasVersion)
                                    {
                                        string version = record.GetString(2) ?? this.Version;
                                        string displayName = record.GetString(3) ?? this.DisplayName;
                                        int attributes = record.GetInteger(4);

                                        dependency = new ProvidesDependency(providerKey, version, displayName, attributes);
                                    }
                                    else
                                    {
                                        int attributes = record.GetInteger(2);

                                        dependency = new ProvidesDependency(providerKey, this.Version, this.DisplayName, attributes);
                                    }

                                    dependency.Imported = true;
                                    this.Provides.Add(dependency);
                                }
                            }
                        }
                    }
                }
            }
            catch (Microsoft.Deployment.WindowsInstaller.InstallerException e)
            {
                this.core.OnMessage(WixErrors.UnableToReadPackageInformation(this.PackagePayload.SourceLineNumbers, sourcePath, e.Message));
            }
        }
Exemple #8
0
        public ChainPackageInfo(Row chainPackageRow, Table wixGroupTable, Dictionary<string, PayloadInfoRow> allPayloads, Dictionary<string, ContainerInfo> containers, BinderFileManager fileManager, BinderCore core, Output bundle) : base(chainPackageRow.SourceLineNumbers, bundle.Tables["ChainPackageInfo"])
        {
            string id = (string)chainPackageRow[0];
            string packageType = (string)chainPackageRow[1];
            string payloadId = (string)chainPackageRow[2];
            string installCondition = (string)chainPackageRow[3];
            string installCommand = (string)chainPackageRow[4];
            string repairCommand = (string)chainPackageRow[5];
            string uninstallCommand = (string)chainPackageRow[6];
            object cacheData = chainPackageRow[7];
            string cacheId = (string)chainPackageRow[8];
            object attributesData = chainPackageRow[9];
            object vitalData = chainPackageRow[10];
            object perMachineData = chainPackageRow[11];
            string detectCondition = (string)chainPackageRow[12];
            string msuKB = (string)chainPackageRow[13];
            object repairableData = chainPackageRow[14];
            string logPathVariable = (string)chainPackageRow[15];
            string rollbackPathVariable = (string)chainPackageRow[16];
            string protocol = (string)chainPackageRow[17];
            long installSize = (int)chainPackageRow[18];
            object suppressLooseFilePayloadGenerationData = chainPackageRow[19];
            object enableFeatureSelectionData = chainPackageRow[20];
            object forcePerMachineData = chainPackageRow[21];
            object displayInternalUIData = chainPackageRow[22];

            BundlePackageAttributes attributes = (null == attributesData) ? 0 : (BundlePackageAttributes)attributesData;

            YesNoAlwaysType cache = YesNoAlwaysType.NotSet;
            if (null != cacheData)
            {
                switch ((int)cacheData)
                {
                    case 0:
                        cache = YesNoAlwaysType.No;
                        break;
                    case 1:
                        cache = YesNoAlwaysType.Yes;
                        break;
                    case 2:
                        cache = YesNoAlwaysType.Always;
                        break;
                }
            }

            YesNoType vital = (null == vitalData || 1 == (int)vitalData) ? YesNoType.Yes : YesNoType.No;

            YesNoDefaultType perMachine = YesNoDefaultType.NotSet;
            if (null != perMachineData)
            {
                switch ((int)perMachineData)
                {
                    case 0:
                        perMachine = YesNoDefaultType.No;
                        break;
                    case 1:
                        perMachine = YesNoDefaultType.Yes;
                        break;
                    case 2:
                        perMachine = YesNoDefaultType.Default;
                        break;
                }
            }

            YesNoType repairable = YesNoType.NotSet;
            if (null != repairableData)
            {
                repairable = (1 == (int)repairableData) ? YesNoType.Yes : YesNoType.No;
            }

            YesNoType suppressLooseFilePayloadGeneration = YesNoType.NotSet;
            if (null != suppressLooseFilePayloadGenerationData)
            {
                suppressLooseFilePayloadGeneration = (1 == (int)suppressLooseFilePayloadGenerationData) ? YesNoType.Yes : YesNoType.No;
            }

            YesNoType enableFeatureSelection = YesNoType.NotSet;
            if (null != enableFeatureSelectionData)
            {
                enableFeatureSelection = (1 == (int)enableFeatureSelectionData) ? YesNoType.Yes : YesNoType.No;
            }

            YesNoType forcePerMachine = YesNoType.NotSet;
            if (null != forcePerMachineData)
            {
                forcePerMachine = (1 == (int)forcePerMachineData) ? YesNoType.Yes : YesNoType.No;
            }

            YesNoType displayInternalUI = YesNoType.NotSet;
            if (null != displayInternalUIData)
            {
                displayInternalUI = (1 == (int)displayInternalUIData) ? YesNoType.Yes : YesNoType.No;
            }

            this.core = core;

            this.Id = id;
            this.ChainPackageType = (Compiler.ChainPackageType)Enum.Parse(typeof(Compiler.ChainPackageType), packageType, true);
            PayloadInfoRow packagePayload;
            if (!allPayloads.TryGetValue(payloadId, out packagePayload))
            {
                this.core.OnMessage(WixErrors.IdentifierNotFound("Payload", payloadId));
                return;
            }
            this.PackagePayload = packagePayload;
            this.InstallCondition = installCondition;
            this.InstallCommand = installCommand;
            this.RepairCommand = repairCommand;
            this.UninstallCommand = uninstallCommand;

            this.PerMachine = perMachine;
            this.ProductCode = null;
            this.Cache = YesNoAlwaysType.NotSet == cache ? YesNoAlwaysType.Yes : cache; // The default is yes.
            this.CacheId = cacheId;
            this.Permanent = (BundlePackageAttributes.Permanent == (attributes & BundlePackageAttributes.Permanent));
            this.Visible = (BundlePackageAttributes.Visible == (attributes & BundlePackageAttributes.Visible));
            this.Slipstream = (BundlePackageAttributes.Slipstream == (attributes & BundlePackageAttributes.Slipstream));
            this.Vital = (YesNoType.Yes == vital); // true only when specifically requested.
            this.DetectCondition = detectCondition;
            this.MsuKB = msuKB;
            this.Protocol = protocol;
            this.Repairable = (YesNoType.Yes == repairable); // true only when specifically requested.
            this.LogPathVariable = logPathVariable;
            this.RollbackLogPathVariable = rollbackPathVariable;

            this.DisplayInternalUI = (YesNoType.Yes == displayInternalUI);

            this.Payloads = new List<PayloadInfoRow>();
            this.RelatedPackages = new List<RelatedPackage>();
            this.MsiFeatures = new List<MsiFeature>();
            this.MsiProperties = new List<MsiPropertyInfo>();
            this.SlipstreamMsps = new List<string>();
            this.ExitCodes = new List<ExitCodeInfo>();
            this.Provides = new ProvidesDependencyCollection();
            this.TargetCodes = new RowDictionary<WixBundlePatchTargetCodeRow>();

            // Default the display name and description to the package payload.
            this.DisplayName = this.PackagePayload.ProductName;
            this.Description = this.PackagePayload.Description;

            // Start the package size with the package's payload size.
            this.Size = this.PackagePayload.FileSize;

            // get all contained payloads...
            foreach (Row row in wixGroupTable.Rows)
            {
                string rowParentName = (string)row[0];
                string rowParentType = (string)row[1];
                string rowChildName = (string)row[2];
                string rowChildType = (string)row[3];

                if ("Package" == rowParentType && this.Id == rowParentName &&
                    "Payload" == rowChildType && this.PackagePayload.Id != rowChildName)
                {
                    PayloadInfoRow payload = allPayloads[rowChildName];
                    this.Payloads.Add(payload);

                    this.Size += payload.FileSize; // add each payload to the total size of the package.
                }
            }

            // Default the install size to the calculated package size.
            this.InstallSize = this.Size;

            switch (this.ChainPackageType)
            {
                case Compiler.ChainPackageType.Msi:
                    this.ResolveMsiPackage(fileManager, allPayloads, containers, suppressLooseFilePayloadGeneration, enableFeatureSelection, forcePerMachine, bundle);
                    break;
                case Compiler.ChainPackageType.Msp:
                    this.ResolveMspPackage(bundle);
                    break;
                case Compiler.ChainPackageType.Msu:
                    this.ResolveMsuPackage();
                    break;
                case Compiler.ChainPackageType.Exe:
                    this.ResolveExePackage();
                    break;
            }

            if (CompilerCore.IntegerNotSet != installSize)
            {
                this.InstallSize = installSize;
            }
        }
Exemple #9
0
 public ContainerInfo(Row row, BinderFileManager fileManager)
     : this((string)row[0], (string)row[1], (string)row[2], (string)row[3], fileManager)
 {
     this.SourceLineNumbers = row.SourceLineNumbers;
 }
Exemple #10
0
 public ContainerInfo(Row row, BinderFileManager fileManager)
     : this((string)row[0], (string)row[1], (string)row[2], (string)row[3], fileManager)
 {
     this.SourceLineNumbers = row.SourceLineNumbers;
 }
Exemple #11
0
 public ContainerInfo(string id, string name, string type, string downloadUrl, BinderFileManager fileManager)
 {
     this.Id          = id;
     this.Name        = name;
     this.Type        = type;
     this.DownloadUrl = downloadUrl;
     this.FileManager = fileManager;
     this.TempPath    = Path.Combine(fileManager.TempFilesLocation, name);
     this.FileInfo    = new FileInfo(this.TempPath);
 }
Exemple #12
0
        /// <summary>
        /// Saves an output to a path on disk.
        /// </summary>
        /// <param name="path">Path to save output file to on disk.</param>
        /// <param name="binderFileManager">If provided, the binder file manager is used to bind files into the output.</param>
        /// <param name="wixVariableResolver">The Wix variable resolver.</param>
        /// <param name="tempFilesLocation">Location for temporary files.</param>
        public void Save(string path, BinderFileManager binderFileManager, WixVariableResolver wixVariableResolver, string tempFilesLocation)
        {
            FileMode fileMode = FileMode.Create;

            // Assure the location to output the xml exists
            Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path)));

            // Check if there was a cab on the output when it was created
            if (SaveCab(path, binderFileManager, wixVariableResolver, tempFilesLocation))
            {
                fileMode = FileMode.Append;
            }

            // save the xml
            using (FileStream fs = new FileStream(path, fileMode))
            {
                XmlWriter writer = null;

                try
                {
                    writer = new XmlTextWriter(fs, System.Text.Encoding.UTF8);

                    writer.WriteStartDocument();
                    this.Persist(writer);
                    writer.WriteEndDocument();
                }
                finally
                {
                    if (null != writer)
                    {
                        writer.Close();
                    }
                }
            }
        }
Exemple #13
0
        private void WriteBurnManifestPayloadAttributes(XmlTextWriter writer, PayloadInfoRow payload, bool embeddedOnly, BinderFileManager fileManager, Dictionary<string, PayloadInfoRow> allPayloads)
        {
            Debug.Assert(!embeddedOnly || PackagingType.Embedded == payload.Packaging);

            writer.WriteAttributeString("Id", payload.Id);
            writer.WriteAttributeString("FilePath", payload.Name);
            writer.WriteAttributeString("FileSize", payload.FileSize.ToString(CultureInfo.InvariantCulture));
            writer.WriteAttributeString("Hash", payload.Hash);

            if (payload.LayoutOnly)
            {
                writer.WriteAttributeString("LayoutOnly", "yes");
            }

            if (!String.IsNullOrEmpty(payload.PublicKey))
            {
                writer.WriteAttributeString("CertificateRootPublicKeyIdentifier", payload.PublicKey);
            }

            if (!String.IsNullOrEmpty(payload.Thumbprint))
            {
                writer.WriteAttributeString("CertificateRootThumbprint", payload.Thumbprint);
            }

            switch (payload.Packaging)
            {
                case PackagingType.Embedded: // this means it's in a container.
                    if (!String.IsNullOrEmpty(payload.DownloadUrl))
                    {
                        this.core.OnMessage(WixWarnings.DownloadUrlNotSupportedForEmbeddedPayloads(payload.SourceLineNumbers, payload.Id));
                    }

                    writer.WriteAttributeString("Packaging", "embedded");
                    writer.WriteAttributeString("SourcePath", payload.EmbeddedId);

                    if (Compiler.BurnUXContainerId != payload.Container)
                    {
                        writer.WriteAttributeString("Container", payload.Container);
                    }
                    break;

                case PackagingType.External:
                    string packageId = payload.ParentPackagePayload;
                    string parentUrl = payload.ParentPackagePayload == null ? null : allPayloads[payload.ParentPackagePayload].DownloadUrl;
                    string resolvedUrl = fileManager.ResolveUrl(payload.DownloadUrl, parentUrl, packageId, payload.Id, payload.Name);
                    if (!String.IsNullOrEmpty(resolvedUrl))
                    {
                        writer.WriteAttributeString("DownloadUrl", resolvedUrl);
                    }
                    else if (!String.IsNullOrEmpty(payload.DownloadUrl))
                    {
                        writer.WriteAttributeString("DownloadUrl", payload.DownloadUrl);
                    }

                    writer.WriteAttributeString("Packaging", "external");
                    writer.WriteAttributeString("SourcePath", payload.Name);
                    break;
            }

            if (!String.IsNullOrEmpty(payload.CatalogId))
            {
                writer.WriteAttributeString("Catalog", payload.CatalogId);
            }
        }
        /// <summary>
        /// Resolves the source path of a file.
        /// </summary>
        /// <param name="source">Original source value.</param>
        /// <param name="type">Optional type of source file being resolved.</param>
        /// <param name="sourceLineNumbers">Optional source line of source file being resolved.</param>
        /// <param name="bindStage">The binding stage used to determine what collection of bind paths will be used</param>
        /// <returns>Should return a valid path for the stream to be imported.</returns>
        public virtual string ResolveFile(string source, string type, SourceLineNumberCollection sourceLineNumbers, BindStage bindStage)
        {
            // the following new local variables are used for bind path and protect the changes to object field.
            StringCollection    currentBindPaths      = null;
            NameValueCollection currentNamedBindPaths = null;
            StringCollection    currentSourcePaths    = null;

            if (String.IsNullOrEmpty(source))
            {
                throw new ArgumentNullException("source");
            }

            // Call the original override function first. If it returns an answer then return that,
            // otherwise using the default resolving logic
            string filePath = this.ResolveFile(source, type, sourceLineNumbers);

            if (!String.IsNullOrEmpty(filePath))
            {
                return(filePath);
            }

            // Assign the correct bind path to file manager
            currentSourcePaths    = this.sourcePaths[bindStage];
            currentNamedBindPaths = this.namedBindPaths[bindStage];
            if (BindStage.Target != bindStage && BindStage.Updated != bindStage)
            {
                currentBindPaths = this.bindPaths[bindStage];
            }
            else
            {
                currentBindPaths = this.sourcePaths[bindStage];
            }

            // If the path is rooted, it better exist or we're not going to find it.
            if (Path.IsPathRooted(source))
            {
                if (BinderFileManager.CheckFileExists(source))
                {
                    return(source);
                }
            }
            else // not a rooted path so let's try applying all the different source resolution options.
            {
                const string bindPathOpenString = "!(bindpath.";

                if (source.StartsWith(bindPathOpenString, StringComparison.Ordinal) && source.IndexOf(')') != -1)
                {
                    int      bindpathSignatureLength = bindPathOpenString.Length;
                    string   name   = source.Substring(bindpathSignatureLength, source.IndexOf(')') - bindpathSignatureLength);
                    string[] values = currentNamedBindPaths.GetValues(name);

                    if (null != values)
                    {
                        foreach (string bindPath in values)
                        {
                            // Parse out '\\' chars that separate the "bindpath" variable and the next part of the path,
                            // because Path.Combine() thinks that rooted second paths don't need the first path.
                            string nameSection = string.Empty;
                            int    nameStart   = bindpathSignatureLength + 1 + name.Length; // +1 for the closing bracket.

                            nameSection = source.Substring(nameStart).TrimStart('\\');
                            filePath    = Path.Combine(bindPath, nameSection);

                            if (BinderFileManager.CheckFileExists(filePath))
                            {
                                return(filePath);
                            }
                        }
                    }
                }
                else if (source.StartsWith("SourceDir\\", StringComparison.Ordinal) || source.StartsWith("SourceDir/", StringComparison.Ordinal))
                {
                    foreach (string bindPath in currentBindPaths)
                    {
                        filePath = Path.Combine(bindPath, source.Substring(10));
                        if (BinderFileManager.CheckFileExists(filePath))
                        {
                            return(filePath);
                        }
                    }
                }
                else if (BinderFileManager.CheckFileExists(source))
                {
                    return(source);
                }

                foreach (string path in currentSourcePaths)
                {
                    filePath = Path.Combine(path, source);
                    if (BinderFileManager.CheckFileExists(filePath))
                    {
                        return(filePath);
                    }

                    if (source.StartsWith("SourceDir\\", StringComparison.Ordinal) || source.StartsWith("SourceDir/", StringComparison.Ordinal))
                    {
                        filePath = Path.Combine(path, source.Substring(10));
                        if (BinderFileManager.CheckFileExists(filePath))
                        {
                            return(filePath);
                        }
                    }
                }
            }

            // Didn't find the file.
            throw new WixFileNotFoundException(sourceLineNumbers, source, type);
        }
Exemple #15
0
        /// <summary>
        /// Saves a library to a path on disk.
        /// </summary>
        /// <param name="path">Path to save library file to on disk.</param>
        /// <param name="binderFileManager">If provided, the binder file manager is used to bind files into the library.</param>
        /// <param name="wixVariableResolver">The Wix variable resolver.</param>
        public void Save(string path, BinderFileManager binderFileManager, WixVariableResolver wixVariableResolver)
        {
            FileMode         fileMode = FileMode.Create;
            StringCollection fileIds  = new StringCollection();
            StringCollection files    = new StringCollection();
            int index = 0;

            // resolve paths to files and create the library cabinet file
            foreach (Section section in this.sections)
            {
                foreach (Table table in section.Tables)
                {
                    foreach (Row row in table.Rows)
                    {
                        foreach (Field field in row.Fields)
                        {
                            ObjectField objectField = field as ObjectField;

                            if (null != objectField)
                            {
                                if (null != binderFileManager && null != objectField.Data)
                                {
                                    string cabinetFileId = (index++).ToString(CultureInfo.InvariantCulture);

                                    // resolve wix variables
                                    string resolvedValue = wixVariableResolver.ResolveVariables(row.SourceLineNumbers, (string)objectField.Data, false);
                                    files.Add(binderFileManager.ResolveFile(resolvedValue, table.Name, row.SourceLineNumbers, BindStage.Normal));

                                    // File was successfully resolved so track this cabient file id.
                                    objectField.CabinetFileId = cabinetFileId;
                                    fileIds.Add(cabinetFileId);
                                }
                                else // clear out a previous cabinet file id value
                                {
                                    objectField.CabinetFileId = null;
                                }
                            }
                        }
                    }
                }
            }

            // do not save the library if errors were found while resolving object paths
            if (wixVariableResolver.EncounteredError)
            {
                return;
            }

            // create the cabinet file
            if (0 < fileIds.Count)
            {
                using (WixCreateCab cab = new WixCreateCab(Path.GetFileName(path), Path.GetDirectoryName(path), fileIds.Count, 0, 0, CompressionLevel.Mszip))
                {
                    for (int i = 0; i < fileIds.Count; i++)
                    {
                        cab.AddFile(files[i], fileIds[i]);
                    }
                    cab.Complete();
                }

                // append the library xml to the end of the newly created cabinet file
                fileMode = FileMode.Append;
            }

            // Assure the location to output the lib exists
            Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path)));

            // save the xml
            using (FileStream fs = new FileStream(path, fileMode))
            {
                XmlWriter writer = null;

                try
                {
                    writer = new XmlTextWriter(fs, System.Text.Encoding.UTF8);

                    writer.WriteStartDocument();
                    this.Persist(writer);
                    writer.WriteEndDocument();
                }
                finally
                {
                    if (null != writer)
                    {
                        writer.Close();
                    }
                }
            }
        }
Exemple #16
0
        /// <summary>
        /// Resolves paths to files.
        /// </summary>
        /// <param name="sectionTables">TableCollection of tables to process</param>
        /// <param name="binderFileManager">If provided, the binder file manager is used to bind files into the output.</param>
        /// <param name="wixVariableResolver">The Wix variable resolver.</param>
        /// <param name="tempFilesLocation">Location for temporary files.</param>
        /// <param name="cabinets">Hash of source cabinets.</param>
        /// <param name="fileIds">Collection of CabinetFileIds.</param>
        /// <param name="files">Collection of file paths from compressed files.</param>
        /// <param name="index">CabinetFileId generator.</param>
        public static void ResolveSectionFiles(TableCollection sectionTables, BinderFileManager binderFileManager, WixVariableResolver wixVariableResolver, string tempFilesLocation, Hashtable cabinets, StringCollection fileIds, StringCollection files, ref int index)
        {
            foreach (Table table in sectionTables)
            {
                foreach (Row row in table.Rows)
                {
                    foreach (Field field in row.Fields)
                    {
                        ObjectField objectField = field as ObjectField;

                        if (null != objectField && null != objectField.Data)
                        {
                            string file              = null;
                            string previousFile      = null;
                            bool   isDefault         = true;
                            bool   isPreviousDefault = true;

                            // resolve localization and wix variables if there is a file manager that would use the value
                            // if it was different, otherwise we just don't care so skip the whole variable resolution thing.
                            if (null != wixVariableResolver && null != binderFileManager)
                            {
                                objectField.Data = wixVariableResolver.ResolveVariables(row.SourceLineNumbers, (string)objectField.Data, false, ref isDefault);

                                if (null != objectField.PreviousData)
                                {
                                    objectField.PreviousData = wixVariableResolver.ResolveVariables(row.SourceLineNumbers, objectField.PreviousData, false, ref isPreviousDefault);
                                }

                                // do not save the output if errors were found while resolving object paths
                                if (wixVariableResolver.EncounteredError)
                                {
                                    return;
                                }
                            }

                            // file is compressed in a cabinet (and not modified above)
                            if (null != objectField.CabinetFileId && isDefault)
                            {
                                // index cabinets that have not been previously encountered
                                if (!cabinets.ContainsKey(objectField.BaseUri))
                                {
                                    Uri    baseUri = new Uri(objectField.BaseUri);
                                    string localFileNameWithoutExtension = Path.GetFileNameWithoutExtension(baseUri.LocalPath);
                                    string extractedDirectoryName        = String.Format(CultureInfo.InvariantCulture, "cab_{0}_{1}", cabinets.Count, localFileNameWithoutExtension);

                                    // index the cabinet file's base URI (source location) and extracted directory
                                    cabinets.Add(objectField.BaseUri, Path.Combine(tempFilesLocation, extractedDirectoryName));
                                }

                                // set the path to the file once its extracted from the cabinet
                                file = Path.Combine((string)cabinets[objectField.BaseUri], objectField.CabinetFileId);
                            }
                            else if (null != binderFileManager)
                            {
                                file = binderFileManager.ResolveFile((string)objectField.Data, table.Name, row.SourceLineNumbers, BindStage.Normal);
                            }

                            // add the file to the list of files to go in the cabinet
                            if (null != file)
                            {
                                string cabinetFileId = (index++).ToString(CultureInfo.InvariantCulture);

                                objectField.CabinetFileId = cabinetFileId;
                                fileIds.Add(cabinetFileId);

                                files.Add(file);
                            }

                            // previous file is compressed in a cabinet (and not modified above)
                            if (null != objectField.PreviousCabinetFileId && isPreviousDefault)
                            {
                                // index cabinets that have not been previously encountered
                                if (!cabinets.ContainsKey(objectField.PreviousBaseUri))
                                {
                                    Uri    baseUri = new Uri(objectField.PreviousBaseUri);
                                    string localFileNameWithoutExtension = Path.GetFileNameWithoutExtension(baseUri.LocalPath);
                                    string extractedDirectoryName        = String.Format(CultureInfo.InvariantCulture, "cab_{0}_{1}", cabinets.Count, localFileNameWithoutExtension);

                                    // index the cabinet file's base URI (source location) and extracted directory
                                    cabinets.Add(objectField.PreviousBaseUri, Path.Combine(tempFilesLocation, extractedDirectoryName));
                                }

                                // set the path to the file once its extracted from the cabinet
                                previousFile = Path.Combine((string)cabinets[objectField.PreviousBaseUri], objectField.PreviousCabinetFileId);
                            }
                            else if (null != objectField.PreviousData && null != binderFileManager)
                            {
                                previousFile = binderFileManager.ResolveFile((string)objectField.PreviousData, table.Name, row.SourceLineNumbers, BindStage.Normal);
                            }

                            // add the file to the list of files to go in the cabinet
                            if (null != previousFile)
                            {
                                string cabinetFileId = (index++).ToString(CultureInfo.InvariantCulture);

                                objectField.PreviousCabinetFileId = cabinetFileId;
                                fileIds.Add(cabinetFileId);

                                files.Add(previousFile);
                            }
                        }
                    }
                }
            }
        }
        public virtual CabinetBuildOption ResolveCabinet(FileRowCollection fileRows, ref string cabinetPath)
        {
            if (fileRows == null)
            {
                throw new ArgumentNullException("fileRows");
            }

            // no special behavior specified, use the default
            if (null == this.cabCachePath && !this.reuseCabinets)
            {
                return(CabinetBuildOption.BuildAndMove);
            }

            // if a cabinet cache path was provided, change the location for the cabinet
            // to be built to
            if (null != this.cabCachePath)
            {
                string cabinetName = Path.GetFileName(cabinetPath);
                cabinetPath = Path.Combine(this.cabCachePath, cabinetName);
            }

            // if we still think we're going to reuse the cabinet check to see if the cabinet exists first
            if (this.reuseCabinets)
            {
                bool cabinetValid = false;

                if (BinderFileManager.CheckFileExists(cabinetPath))
                {
                    // check to see if
                    // 1. any files are added or removed
                    // 2. order of files changed or names changed
                    // 3. modified time changed
                    cabinetValid = true;

                    // Need to force garbage collection of WixEnumerateCab to ensure the handle
                    // associated with it is closed before it is reused.
                    using (Cab.WixEnumerateCab wixEnumerateCab = new Cab.WixEnumerateCab())
                    {
                        ArrayList fileList = wixEnumerateCab.Enumerate(cabinetPath);

                        if (fileRows.Count != fileList.Count)
                        {
                            cabinetValid = false;
                        }
                        else
                        {
                            int i = 0;
                            foreach (FileRow fileRow in fileRows)
                            {
                                // First check that the file identifiers match because that is quick and easy.
                                CabinetFileInfo cabFileInfo = fileList[i] as CabinetFileInfo;
                                cabinetValid = (cabFileInfo.FileId == fileRow.File);
                                if (cabinetValid)
                                {
                                    // Still valid so ensure the source time stamp hasn't changed. Thus we need
                                    // to convert the source file time stamp into a cabinet compatible data/time.
                                    DateTime sourceFileTime = File.GetLastWriteTime(fileRow.Source);
                                    ushort   sourceCabDate;
                                    ushort   sourceCabTime;

                                    Cab.Interop.CabInterop.DateTimeToCabDateAndTime(sourceFileTime, out sourceCabDate, out sourceCabTime);
                                    cabinetValid = (cabFileInfo.Date == sourceCabDate && cabFileInfo.Time == sourceCabTime);
                                }

                                if (!cabinetValid)
                                {
                                    break;
                                }

                                i++;
                            }
                        }
                    }
                }

                return(cabinetValid ? CabinetBuildOption.Copy : CabinetBuildOption.BuildAndCopy);
            }
            else // by default move the built cabinet
            {
                return(CabinetBuildOption.BuildAndMove);
            }
        }
Exemple #18
0
        /// <summary>
        /// Saves an outputs cab to a path on disk.
        /// </summary>
        /// <param name="path">Path to save outputs cab to on disk.</param>
        /// <param name="binderFileManager">If provided, the binder file manager is used to bind files into the outputs cab.</param>
        /// <param name="wixVariableResolver">The Wix variable resolver.</param>
        /// <param name="tempFilesLocation">Location for temporary files.</param>
        /// <returns>Returns true if a cabinet existed or was created, false otherwise.</returns>
        public bool SaveCab(string path, BinderFileManager binderFileManager, WixVariableResolver wixVariableResolver, string tempFilesLocation)
        {
            bool hasCab = false;

            // Check if there was a cab on the wixout when it was created
            if (null != this.cabPath)
            {
                // There was already a cab on the wixout when it was loaded. Reuse that one.
                File.Copy(this.cabPath, path, true);
                if (null != this.tempFileCollection)
                {
                    this.tempFileCollection.Delete();
                }
                hasCab = true;
            }
            else
            {
                int              index    = 0;
                Hashtable        cabinets = new Hashtable();
                StringCollection fileIds  = new StringCollection();
                StringCollection files    = new StringCollection();

                if (null != tempFilesLocation)
                {
                    // resolve paths to files and create the output cabinet file
                    if (0 == this.sections.Count)
                    {
                        Output.ResolveSectionFiles(this.tables, binderFileManager, wixVariableResolver, tempFilesLocation, cabinets, fileIds, files, ref index);
                    }
                    else
                    {
                        foreach (Section section in this.sections)
                        {
                            Output.ResolveSectionFiles(section.Tables, binderFileManager, wixVariableResolver, tempFilesLocation, cabinets, fileIds, files, ref index);
                        }
                    }
                }

                // extract files that come from cabinet files
                if (0 < cabinets.Count)
                {
                    // ensure the temporary directory exists
                    Directory.CreateDirectory(tempFilesLocation);

                    foreach (DictionaryEntry cabinet in cabinets)
                    {
                        Uri    baseUri = new Uri((string)cabinet.Key);
                        string localPath;

                        if ("embeddedresource" == baseUri.Scheme)
                        {
                            int    bytesRead;
                            byte[] buffer = new byte[512];

                            string   originalLocalPath = Path.GetFullPath(baseUri.LocalPath.Substring(1));
                            string   resourceName      = baseUri.Fragment.Substring(1);
                            Assembly assembly          = Assembly.LoadFile(originalLocalPath);

                            localPath = String.Concat(cabinet.Value, ".cab");

                            using (FileStream fs = File.OpenWrite(localPath))
                            {
                                using (Stream resourceStream = assembly.GetManifestResourceStream(resourceName))
                                {
                                    while (0 < (bytesRead = resourceStream.Read(buffer, 0, buffer.Length)))
                                    {
                                        fs.Write(buffer, 0, bytesRead);
                                    }
                                }
                            }
                        }
                        else // normal file
                        {
                            localPath = baseUri.LocalPath;
                        }

                        // extract the cabinet's files into a temporary directory
                        Directory.CreateDirectory((string)cabinet.Value);

                        using (WixExtractCab extractCab = new WixExtractCab())
                        {
                            extractCab.Extract(localPath, (string)cabinet.Value);
                        }
                    }
                }

                // create the cabinet file
                if (0 < fileIds.Count)
                {
                    using (WixCreateCab cab = new WixCreateCab(Path.GetFileName(path), Path.GetDirectoryName(path), fileIds.Count, 0, 0, CompressionLevel.Mszip))
                    {
                        for (int i = 0; i < fileIds.Count; i++)
                        {
                            cab.AddFile(files[i], fileIds[i]);
                        }
                        cab.Complete();
                    }

                    // append the output xml to the end of the newly created cabinet file
                    hasCab = true;
                }
            }

            return(hasCab);
        }
Exemple #19
0
        /// <summary>
        /// Saves a library to a path on disk.
        /// </summary>
        /// <param name="path">Path to save library file to on disk.</param>
        /// <param name="binderFileManager">If provided, the binder file manager is used to bind files into the library.</param>
        /// <param name="wixVariableResolver">The Wix variable resolver.</param>
        public void Save(string path, BinderFileManager binderFileManager, WixVariableResolver wixVariableResolver)
        {
            FileMode fileMode = FileMode.Create;
            StringCollection fileIds = new StringCollection();
            StringCollection files = new StringCollection();
            int index = 0;

            // resolve paths to files and create the library cabinet file
            foreach (Section section in this.sections)
            {
                foreach (Table table in section.Tables)
                {
                    foreach (Row row in table.Rows)
                    {
                        foreach (Field field in row.Fields)
                        {
                            ObjectField objectField = field as ObjectField;

                            if (null != objectField)
                            {
                                if (null != binderFileManager && null != objectField.Data)
                                {
                                    string cabinetFileId = (index++).ToString(CultureInfo.InvariantCulture);

                                    // resolve wix variables
                                    string resolvedValue = wixVariableResolver.ResolveVariables(row.SourceLineNumbers, (string)objectField.Data, false);
                                    files.Add(binderFileManager.ResolveFile(resolvedValue, table.Name, row.SourceLineNumbers, BindStage.Normal));

                                    // File was successfully resolved so track this cabient file id.
                                    objectField.CabinetFileId = cabinetFileId;
                                    fileIds.Add(cabinetFileId);
                                }
                                else // clear out a previous cabinet file id value
                                {
                                    objectField.CabinetFileId = null;
                                }
                            }
                        }
                    }
                }
            }

            // do not save the library if errors were found while resolving object paths
            if (wixVariableResolver.EncounteredError)
            {
                return;
            }

            // create the cabinet file
            if (0 < fileIds.Count)
            {
                using (WixCreateCab cab = new WixCreateCab(Path.GetFileName(path), Path.GetDirectoryName(path), fileIds.Count, 0, 0, CompressionLevel.Mszip))
                {
                    for (int i = 0; i < fileIds.Count; i++)
                    {
                        cab.AddFile(files[i], fileIds[i]);
                    }
                    cab.Complete();
                }

                // append the library xml to the end of the newly created cabinet file
                fileMode = FileMode.Append;
            }

            // Assure the location to output the lib exists
            Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path)));

            // save the xml
            using (FileStream fs = new FileStream(path, fileMode))
            {
                XmlWriter writer = null;

                try
                {
                    writer = new XmlTextWriter(fs, System.Text.Encoding.UTF8);

                    writer.WriteStartDocument();
                    this.Persist(writer);
                    writer.WriteEndDocument();
                }
                finally
                {
                    if (null != writer)
                    {
                        writer.Close();
                    }
                }
            }
        }
Exemple #20
0
        /// <summary>
        /// Resolves paths to files.
        /// </summary>
        /// <param name="sectionTables">TableCollection of tables to process</param>
        /// <param name="binderFileManager">If provided, the binder file manager is used to bind files into the output.</param>
        /// <param name="wixVariableResolver">The Wix variable resolver.</param>
        /// <param name="tempFilesLocation">Location for temporary files.</param>
        /// <param name="cabinets">Hash of source cabinets.</param>
        /// <param name="fileIds">Collection of CabinetFileIds.</param>
        /// <param name="files">Collection of file paths from compressed files.</param>
        /// <param name="index">CabinetFileId generator.</param>
        public static void ResolveSectionFiles(TableCollection sectionTables, BinderFileManager binderFileManager, WixVariableResolver wixVariableResolver, string tempFilesLocation, Hashtable cabinets, StringCollection fileIds, StringCollection files, ref int index)
        {
            foreach (Table table in sectionTables)
            {
                foreach (Row row in table.Rows)
                {
                    foreach (Field field in row.Fields)
                    {
                        ObjectField objectField = field as ObjectField;

                        if (null != objectField && null != objectField.Data)
                        {
                            string file = null;
                            string previousFile = null;
                            bool isDefault = true;
                            bool isPreviousDefault = true;

                            // resolve localization and wix variables if there is a file manager that would use the value
                            // if it was different, otherwise we just don't care so skip the whole variable resolution thing.
                            if (null != wixVariableResolver && null != binderFileManager)
                            {
                                objectField.Data = wixVariableResolver.ResolveVariables(row.SourceLineNumbers, (string)objectField.Data, false, ref isDefault);

                                if (null != objectField.PreviousData)
                                {
                                    objectField.PreviousData = wixVariableResolver.ResolveVariables(row.SourceLineNumbers, objectField.PreviousData, false, ref isPreviousDefault);
                                }

                                // do not save the output if errors were found while resolving object paths
                                if (wixVariableResolver.EncounteredError)
                                {
                                    return;
                                }
                            }

                            // file is compressed in a cabinet (and not modified above)
                            if (null != objectField.CabinetFileId && isDefault)
                            {
                                // index cabinets that have not been previously encountered
                                if (!cabinets.ContainsKey(objectField.BaseUri))
                                {
                                    Uri baseUri = new Uri(objectField.BaseUri);
                                    string localFileNameWithoutExtension = Path.GetFileNameWithoutExtension(baseUri.LocalPath);
                                    string extractedDirectoryName = String.Format(CultureInfo.InvariantCulture, "cab_{0}_{1}", cabinets.Count, localFileNameWithoutExtension);

                                    // index the cabinet file's base URI (source location) and extracted directory
                                    cabinets.Add(objectField.BaseUri, Path.Combine(tempFilesLocation, extractedDirectoryName));
                                }

                                // set the path to the file once its extracted from the cabinet
                                file = Path.Combine((string)cabinets[objectField.BaseUri], objectField.CabinetFileId);
                            }
                            else if (null != binderFileManager)
                            {
                                file = binderFileManager.ResolveFile((string)objectField.Data, table.Name, row.SourceLineNumbers, BindStage.Normal);
                            }

                            // add the file to the list of files to go in the cabinet
                            if (null != file)
                            {
                                string cabinetFileId = (index++).ToString(CultureInfo.InvariantCulture);

                                objectField.CabinetFileId = cabinetFileId;
                                fileIds.Add(cabinetFileId);

                                files.Add(file);
                            }

                            // previous file is compressed in a cabinet (and not modified above)
                            if (null != objectField.PreviousCabinetFileId && isPreviousDefault)
                            {
                                // index cabinets that have not been previously encountered
                                if (!cabinets.ContainsKey(objectField.PreviousBaseUri))
                                {
                                    Uri baseUri = new Uri(objectField.PreviousBaseUri);
                                    string localFileNameWithoutExtension = Path.GetFileNameWithoutExtension(baseUri.LocalPath);
                                    string extractedDirectoryName = String.Format(CultureInfo.InvariantCulture, "cab_{0}_{1}", cabinets.Count, localFileNameWithoutExtension);

                                    // index the cabinet file's base URI (source location) and extracted directory
                                    cabinets.Add(objectField.PreviousBaseUri, Path.Combine(tempFilesLocation, extractedDirectoryName));
                                }

                                // set the path to the file once its extracted from the cabinet
                                previousFile = Path.Combine((string)cabinets[objectField.PreviousBaseUri], objectField.PreviousCabinetFileId);
                            }
                            else if (null != objectField.PreviousData && null != binderFileManager)
                            {
                                previousFile = binderFileManager.ResolveFile((string)objectField.PreviousData, table.Name, row.SourceLineNumbers, BindStage.Normal);
                            }

                            // add the file to the list of files to go in the cabinet
                            if (null != previousFile)
                            {
                                string cabinetFileId = (index++).ToString(CultureInfo.InvariantCulture);

                                objectField.PreviousCabinetFileId = cabinetFileId;
                                fileIds.Add(cabinetFileId);

                                files.Add(previousFile);
                            }
                        }
                    }
                }
            }
        }
Exemple #21
0
        /// <summary>
        /// Saves an outputs cab to a path on disk.
        /// </summary>
        /// <param name="path">Path to save outputs cab to on disk.</param>
        /// <param name="binderFileManager">If provided, the binder file manager is used to bind files into the outputs cab.</param>
        /// <param name="wixVariableResolver">The Wix variable resolver.</param>
        /// <param name="tempFilesLocation">Location for temporary files.</param>
        /// <returns>Returns true if a cabinet existed or was created, false otherwise.</returns>
        public bool SaveCab(string path, BinderFileManager binderFileManager, WixVariableResolver wixVariableResolver, string tempFilesLocation)
        {
            bool hasCab = false;
            // Check if there was a cab on the wixout when it was created
            if (null != this.cabPath)
            {
                // There was already a cab on the wixout when it was loaded. Reuse that one.
                File.Copy(this.cabPath, path, true);
                if (null != this.tempFileCollection)
                {
                    this.tempFileCollection.Delete();
                }
                hasCab = true;
            }
            else
            {
                int index = 0;
                Hashtable cabinets = new Hashtable();
                StringCollection fileIds = new StringCollection();
                StringCollection files = new StringCollection();

                if (null != tempFilesLocation)
                {
                    // resolve paths to files and create the output cabinet file
                    if (0 == this.sections.Count)
                    {
                        Output.ResolveSectionFiles(this.tables, binderFileManager, wixVariableResolver, tempFilesLocation, cabinets, fileIds, files, ref index);
                    }
                    else
                    {
                        foreach (Section section in this.sections)
                        {
                            Output.ResolveSectionFiles(section.Tables, binderFileManager, wixVariableResolver, tempFilesLocation, cabinets, fileIds, files, ref index);
                        }
                    }
                }

                // extract files that come from cabinet files
                if (0 < cabinets.Count)
                {
                    // ensure the temporary directory exists
                    Directory.CreateDirectory(tempFilesLocation);

                    foreach (DictionaryEntry cabinet in cabinets)
                    {
                        Uri baseUri = new Uri((string)cabinet.Key);
                        string localPath;

                        if ("embeddedresource" == baseUri.Scheme)
                        {
                            int bytesRead;
                            byte[] buffer = new byte[512];

                            string originalLocalPath = Path.GetFullPath(baseUri.LocalPath.Substring(1));
                            string resourceName = baseUri.Fragment.Substring(1);
                            Assembly assembly = Assembly.LoadFile(originalLocalPath);

                            localPath = String.Concat(cabinet.Value, ".cab");

                            using (FileStream fs = File.OpenWrite(localPath))
                            {
                                using (Stream resourceStream = assembly.GetManifestResourceStream(resourceName))
                                {
                                    while (0 < (bytesRead = resourceStream.Read(buffer, 0, buffer.Length)))
                                    {
                                        fs.Write(buffer, 0, bytesRead);
                                    }
                                }
                            }
                        }
                        else // normal file
                        {
                            localPath = baseUri.LocalPath;
                        }

                        // extract the cabinet's files into a temporary directory
                        Directory.CreateDirectory((string)cabinet.Value);

                        using (WixExtractCab extractCab = new WixExtractCab())
                        {
                            extractCab.Extract(localPath, (string)cabinet.Value);
                        }
                    }
                }

                // create the cabinet file
                if (0 < fileIds.Count)
                {
                    using (WixCreateCab cab = new WixCreateCab(Path.GetFileName(path), Path.GetDirectoryName(path), fileIds.Count, 0, 0, CompressionLevel.Mszip))
                    {
                        for (int i = 0; i < fileIds.Count; i++)
                        {
                            cab.AddFile(files[i], fileIds[i]);
                        }
                        cab.Complete();
                    }

                    // append the output xml to the end of the newly created cabinet file
                    hasCab = true;
                }
            }

            return hasCab;
        }
Exemple #22
0
        private void WriteBurnManifestContainerAttributes(XmlTextWriter writer, string executableName, ContainerInfo container, int containerIndex, BinderFileManager fileManager)
        {
            writer.WriteAttributeString("Id", container.Id);
            writer.WriteAttributeString("FileSize", container.FileInfo.Length.ToString(CultureInfo.InvariantCulture));
            writer.WriteAttributeString("Hash", Common.GetFileHash(container.FileInfo));
            if (container.Type == "detached")
            {
                string resolvedUrl = fileManager.ResolveUrl(container.DownloadUrl, null, null, container.Id, container.Name);
                if (!String.IsNullOrEmpty(resolvedUrl))
                {
                    writer.WriteAttributeString("DownloadUrl", resolvedUrl);
                }
                else if (!String.IsNullOrEmpty(container.DownloadUrl))
                {
                    writer.WriteAttributeString("DownloadUrl", container.DownloadUrl);
                }

                writer.WriteAttributeString("FilePath", container.Name);
            }
            else if (container.Type == "attached")
            {
                if (!String.IsNullOrEmpty(container.DownloadUrl))
                {
                    this.core.OnMessage(WixWarnings.DownloadUrlNotSupportedForAttachedContainers(container.SourceLineNumbers, container.Id));
                }

                writer.WriteAttributeString("FilePath", executableName); // attached containers use the name of the bundle since they are attached to the executable.
                writer.WriteAttributeString("AttachedIndex", containerIndex.ToString(CultureInfo.InvariantCulture));
                writer.WriteAttributeString("Attached", "yes");
                writer.WriteAttributeString("Primary", "yes");
            }
        }