Beispiel #1
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();
                    }
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Creates a cabinet using the wixcab.dll interop layer.
        /// </summary>
        /// <param name="cabinetWorkItem">CabinetWorkItem containing information about the cabinet to create.</param>
        private void CreateCabinet(CabinetWorkItem cabinetWorkItem)
        {
            this.OnMessage(WixVerboses.CreateCabinet(cabinetWorkItem.CabinetFile));

            int maxCabinetSize = 0; // The value of 0 corresponds to default of 2GB which means no cabinet splitting
            ulong maxPreCompressedSizeInBytes = 0;

            if (MaximumCabinetSizeForLargeFileSplitting != 0)
            {
                // User Specified Max Cab Size for File Splitting, So Check if this cabinet has a single file larger than MaximumUncompressedFileSize
                // If a file is larger than MaximumUncompressedFileSize, then the cabinet containing it will have only this file
                if (cabinetWorkItem.FileRows.Count == 1)
                {
                    // Cabinet has Single File, Check if this is Large File than needs Splitting into Multiple cabs
                    // Get the Value for Max Uncompressed Media Size
                    maxPreCompressedSizeInBytes = (ulong)MaximumUncompressedMediaSize * 1024 * 1024;

                    foreach (FileRow fileRow in cabinetWorkItem.FileRows) // No other easy way than looping to get the only row
                    {
                        if ((ulong)fileRow.FileSize >= maxPreCompressedSizeInBytes)
                        {
                            // If file is larger than MaximumUncompressedFileSize set Maximum Cabinet Size for Cabinet Splitting
                            maxCabinetSize = MaximumCabinetSizeForLargeFileSplitting;
                        }
                    }
                }
            }

            // create the cabinet file
            string cabinetFileName = Path.GetFileName(cabinetWorkItem.CabinetFile);
            string cabinetDirectory = Path.GetDirectoryName(cabinetWorkItem.CabinetFile);

            using (WixCreateCab cab = new WixCreateCab(cabinetFileName, cabinetDirectory, cabinetWorkItem.FileRows.Count, maxCabinetSize, cabinetWorkItem.MaxThreshold, cabinetWorkItem.CompressionLevel))
            {
                foreach (FileRow fileRow in cabinetWorkItem.FileRows)
                {
                    bool retainRangeWarning;
                    cabinetWorkItem.BinderFileManager.ResolvePatch(fileRow, out retainRangeWarning);
                    if (retainRangeWarning)
                    {
                        // TODO: get patch family to add to warning message for PatchWiz parity.
                        this.OnMessage(WixWarnings.RetainRangeMismatch(fileRow.SourceLineNumbers, fileRow.File));
                    }
                    cab.AddFile(fileRow);
               }
                cab.Complete(newCabNamesCallBackAddress);
            }
        }
Beispiel #3
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;
        }
Beispiel #4
0
        private void CreateContainer(ContainerInfo container, string manifestFile)
        {
            int payloadCount = container.Payloads.Count; // The number of embedded payloads
            if (!String.IsNullOrEmpty(manifestFile))
            {
                ++payloadCount;
            }

            using (WixCreateCab cab = new WixCreateCab(Path.GetFileName(container.TempPath), Path.GetDirectoryName(container.TempPath), payloadCount, 0, 0, this.defaultCompressionLevel))
            {
                // If a manifest was provided always add it as "payload 0" to the container.
                if (!String.IsNullOrEmpty(manifestFile))
                {
                    cab.AddFile(manifestFile, "0");
                }

                foreach (PayloadInfoRow payload in container.Payloads)
                {
                    Debug.Assert(PackagingType.Embedded == payload.Packaging);
                    this.core.OnMessage(WixVerboses.LoadingPayload(payload.FullFileName));
                    cab.AddFile(payload.FullFileName, payload.EmbeddedId);
                }

                cab.Complete();
            }
        }
Beispiel #5
0
        /// <summary>
        /// Creates a cabinet using the wixcab.dll interop layer.
        /// </summary>
        /// <param name="cabinetDir">Directory to create cabinet in.</param>
        /// <param name="cabinetName">Name of cabinet to create.</param>
        /// <param name="level">Level of compression to compress with.</param>
        /// <param name="files">Array of files to put into cabinet.</param>
        /// <param name="importStreams">Collection of import streams to add cabinet to if embedding.</param>
        /// <param name="fileTransfers">Array of files to be transfered.</param>
        private void CreateCabinet(string cabinetDir, string cabinetName, CompressionLevel level, ArrayList files, ImportStreamCollection importStreams, ArrayList fileTransfers)
        {
            if (0 == files.Count || this.foundError)
            {
                return;
            }

            bool embedCabinet;
            string cabinetPath;
            string[] fileIds = new string[files.Count];
            string[] filePaths = new string[files.Count];

            // if the cabinet is embedded
            if (cabinetName.StartsWith("#"))
            {
                cabinetName = cabinetName.Substring(1);
                cabinetPath = Path.Combine(this.tempFiles.BasePath, cabinetName);

                embedCabinet = true;
            }
            else // cabinet is not embedded
            {
                cabinetPath = Path.Combine(this.tempFiles.BasePath, cabinetName);
                embedCabinet = false;
            }

            for (int i = 0; i < files.Count; i++)
            {
                FileMediaInformation fmi = (FileMediaInformation)files[i];

                fileIds[i] = fmi.File;
                try
                {
                    filePaths[i] = this.extension.FileResolutionHandler(fmi.Source, FileResolutionType.File);
                }
                catch (WixFileNotFoundException wfnfe)
                {
                    this.OnMessage(WixErrors.BinderExtensionMissingFile(null, ErrorLevel.Normal, wfnfe.Message));
                    continue;
                }

                this.OnMessage(WixVerboses.CabFile(null, VerboseLevel.Verbose, fileIds[i], filePaths[i]));
            }

            if (this.foundError)
            {
                // Don't create the cabinet if errors have been found.
                return;
            }

            CabinetBuildOption cabinetBuildOption = this.extension.CabinetResolutionHandler(fileIds, filePaths, ref cabinetPath);

            // build the cabinet if its not being skipped
            if (CabinetBuildOption.BuildAndCopy == cabinetBuildOption || CabinetBuildOption.BuildAndMove == cabinetBuildOption)
            {
                WixCreateCab cab = null;
                try
                {
                    cab = new WixCreateCab(Path.GetFileName(cabinetPath), Path.GetDirectoryName(cabinetPath), 0, 0, level);
                    cab.AddFiles(filePaths, fileIds, false);
                }
                catch (WixCabCreationException wcce)
                {
                    if (null != wcce.FileName)
                    {
                        this.OnMessage(WixErrors.CabCreationFailed(cabinetPath, wcce.FileName, wcce.ErrorCode));
                    }
                    else
                    {
                        this.OnMessage(WixErrors.CabCreationFailed(cabinetPath, wcce.ErrorCode));
                    }
                }
                catch (FileNotFoundException fnfe)
                {
                    throw new WixFileNotFoundException(null, fnfe.FileName, fnfe);
                }
                finally
                {
                    if (null != cab)
                    {
                        try
                        {
                            cab.Close();
                        }
                        catch (WixCabCreationException)
                        {
                            this.OnMessage(WixErrors.CabClosureFailed(cabinetPath));
                        }
                    }
                }
            }

            if (embedCabinet)
            {
                importStreams.Add(new ImportStream(ImportStreamType.Cabinet, cabinetName, cabinetPath));
            }
            else
            {
                string destinationPath = Path.Combine(cabinetDir, cabinetName);
                fileTransfers.Add(new FileTransfer(cabinetPath, destinationPath, CabinetBuildOption.BuildAndMove == cabinetBuildOption));
            }
        }
        /// <summary>
        /// Creates a cabinet using the wixcab.dll interop layer.
        /// </summary>
        /// <param name="cabinetWorkItem">CabinetWorkItem containing information about the cabinet to create.</param>
        private void CreateCabinet(CabinetWorkItem cabinetWorkItem)
        {
            this.OnMessage(WixVerboses.CreateCabinet(cabinetWorkItem.CabinetFile));

            // create the cabinet file
            string cabinetFileName = Path.GetFileName(cabinetWorkItem.CabinetFile);
            string cabinetDirectory = Path.GetDirectoryName(cabinetWorkItem.CabinetFile);

            using (WixCreateCab cab = new WixCreateCab(cabinetFileName, cabinetDirectory, cabinetWorkItem.FileRows.Count, 0, cabinetWorkItem.MaxThreshold, cabinetWorkItem.CompressionLevel))
            {
                foreach (FileRow fileRow in cabinetWorkItem.FileRows)
                {
                    bool retainRangeWarning;
                    cabinetWorkItem.BinderFileManager.ResolvePatch(fileRow, out retainRangeWarning);
                    if (retainRangeWarning)
                    {
                        // TODO: get patch family to add to warning message for PatchWiz parity.
                        this.OnMessage(WixWarnings.RetainRangeMismatch(fileRow.SourceLineNumbers, fileRow.File));
                    }
                    cab.AddFile(fileRow);
               }
               cab.Complete();
            }
        }