Ejemplo n.º 1
0
        internal void MoveAttributesTo(WixEntity dest)
        {
            var attrs           = this.Attributes;
            var attrsDefinition = this.AttributesDefinition;

            this.Attributes.Clear();
            this.AttributesDefinition = null;
            dest.Attributes           = attrs;
            dest.AttributesDefinition = attrsDefinition;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// For future use
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        private string HashedIdAlgorithm(WixEntity entity)
        {
            if (entity is File file)
            {
                var target_path = this.GetTargetPathOf(file);
                var hash        = target_path.GetHashCode32();

                // WiX does not allow '-' char in ID. So need to use `Math.Abs`
                return($"{target_path.PathGetFileName()}_{Math.Abs(hash)}");
            }
            return(null); // next two lines produce the same result
                          // return WixEntity.DefaultIdAlgorithm(entity);
                          // return WixEntity.IncrementalIdFor(entity);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Algorithm for generating deterministic <see cref="T:WixSharp.File"/>Id(s) based on the hash of the target path.
        /// <para>This algorithm addresses the limitation of the incremental-Id legacy algorithm, which it quite reliable but
        /// non deterministic.</para>
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        public string HashedTargetPathIdAlgorithm(WixEntity entity)
        {
            if (entity is File file)
            {
                var target_path = this.GetTargetPathOf(file);

                var dir_hash  = Math.Abs(target_path.PathGetDirName().GetHashCode32());
                var file_name = target_path.PathGetFileName();

                return($"{file_name}.{dir_hash}");
            }

            return(null); // pass to default Id generator
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Algorithm for generating deterministic <see cref="T:WixSharp.File"/>Id(s) based on the hash of the target path.
        /// <para>This algorithm addresses the limitation of the incremental-Id legacy algorithm, which it quite reliable but
        /// non deterministic.</para>
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        public string HashedTargetPathIdAlgorithm(WixEntity entity)
        {
            if (entity is File file)
            {
                var target_path = this.GetTargetPathOf(file);

                var dir_hash  = Math.Abs(target_path.PathGetDirName().GetHashCode32());
                var file_name = target_path.PathGetFileName().EscapeIllegalCharacters();

                if (Compiler.AutoGeneration.HashedTargetPathIdAlgorithm_FileIdMask != null)
                {
                    return(Compiler.AutoGeneration.HashedTargetPathIdAlgorithm_FileIdMask
                           .Replace("{file_name}", file_name)
                           .Replace("{dir_hash}", dir_hash.ToString())
                           .FormatWith(file_name, dir_hash));
                }
                else
                {
                    return($"{file_name}.{dir_hash}");
                }
            }

            return(null); // pass to default Id generator
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Builds the WiX source file (*.wxs) from the specified <see cref="Bundle"/> instance.
        /// </summary>
        /// <param name="project">The project.</param>
        /// <returns></returns>
        public static string BuildWxs(Bundle project)
        {
            lock (typeof(Compiler))
            {
                //very important to keep "ClientAssembly = " in all "public Build*" methods to ensure GetCallingAssembly
                //returns the build script assembly but not just another method of Compiler.
                if (ClientAssembly.IsEmpty())
                {
                    ClientAssembly = System.Reflection.Assembly.GetCallingAssembly().GetLocation();
                }

                project.Validate();

                lock (Compiler.AutoGeneration.WxsGenerationSynchObject)
                {
                    var oldAlgorithm = AutoGeneration.CustomIdAlgorithm;
                    try
                    {
                        WixEntity.ResetIdGenerator(false);
                        AutoGeneration.CustomIdAlgorithm = project.CustomIdAlgorithm ?? AutoGeneration.CustomIdAlgorithm;

                        string file = IO.Path.GetFullPath(IO.Path.Combine(project.OutDir, project.OutFileName) + ".wxs");

                        if (IO.File.Exists(file))
                        {
                            IO.File.Delete(file);
                        }

                        string extraNamespaces = project.WixNamespaces.Distinct()
                                                 .Select(x => x.StartsWith("xmlns:") ? x : "xmlns:" + x)
                                                 .ConcatItems(" ");

                        var wix3Namespace = "http://schemas.microsoft.com/wix/2006/wi";
                        var wix4Namespace = "http://wixtoolset.org/schemas/v4/wxs";

                        var wixNamespace = Compiler.IsWix4 ? wix4Namespace : wix3Namespace;

                        var doc = XDocument.Parse(
                            @"<?xml version=""1.0"" encoding=""utf-8""?>
                             " + $"<Wix xmlns=\"{wixNamespace}\" {extraNamespaces} " + @" >
                        </Wix>");

                        doc.Root.Add(project.ToXml());

                        AutoElements.NormalizeFilePaths(doc, project.SourceBaseDir, EmitRelativePaths);

                        project.InvokeWixSourceGenerated(doc);

                        AutoElements.ExpandCustomAttributes(doc, project);

                        if (WixSourceGenerated != null)
                        {
                            WixSourceGenerated(doc);
                        }

                        string xml = "";
                        using (IO.StringWriter sw = new StringWriterWithEncoding(Encoding.Default))
                        {
                            doc.Save(sw, SaveOptions.None);
                            xml = sw.ToString();
                        }

                        //of course you can use XmlTextWriter.WriteRaw but this is just a temporary quick'n'dirty solution
                        //http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2657663&SiteID=1
                        xml = xml.Replace("xmlns=\"\"", "");

                        DefaultWixSourceFormatedHandler(ref xml);

                        project.InvokeWixSourceFormated(ref xml);
                        if (WixSourceFormated != null)
                        {
                            WixSourceFormated(ref xml);
                        }

                        using (var sw = new IO.StreamWriter(file, false, Encoding.Default))
                            sw.WriteLine(xml);

                        Compiler.OutputWriteLine("\n----------------------------------------------------------\n");
                        Compiler.OutputWriteLine("Wix project file has been built: " + file + "\n");

                        project.InvokeWixSourceSaved(file);
                        if (WixSourceSaved != null)
                        {
                            WixSourceSaved(file);
                        }

                        return(file);
                    }
                    finally
                    {
                        AutoGeneration.CustomIdAlgorithm = oldAlgorithm;
                    }
                }
            }
        }
Ejemplo n.º 6
0
 internal void ResetAutoIdGeneration(bool supressWarning)
 {
     ResetWixGuidStartValue();
     WixEntity.ResetIdGenerator(supressWarning);
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Index based Id generation algorithm.
        /// <para>It is the default algorithm, which generates the most human readable Id. Thus if the
        /// project has two `index.html` files one will be assigned Id `index.html` and another one
        /// `index.html.1`.</para>
        /// <para> Limitations: If two files have the same name it is non-deterministic which one gets
        /// clear Id and which one the indexed one.</para>
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <returns></returns>
        public static string IncrementalIdFor(WixEntity entity)
        {
            if (!idMaps.ContainsKey(entity.GetType()))
            {
                idMaps[entity.GetType()] = new Dictionary <string, int>();
            }

            var rawName = entity.Name.Expand();

            if (rawName.IsEmpty())
            {
                rawName = entity.GetType().Name;
            }

            if (IO.Path.IsPathRooted(entity.Name))
            {
                rawName = IO.Path.GetFileName(entity.Name).Expand();
            }

            if (entity.GetType() != typeof(Dir) && entity.GetType().BaseType != typeof(Dir) && entity.Name.IsNotEmpty())
            {
                rawName = IO.Path.GetFileName(entity.Name).Expand();
            }

            //Maximum allowed length for a stream name is 62 characters long; In some cases more but to play it safe keep 62 limit
            //
            //Note: the total limit 62 needs to include in some cases MSI auto prefix (e.g. table name) ~15 chars
            // our hash code (max 10 chars) and our decoration (separators). So 30 seems to be a safe call
            //
            int maxLength = 30;

            if (rawName.Length > maxLength)
            {
                //some chars are illegal as star if the ID so work around this with '_' prefix
                rawName = "_..." + rawName.Substring(rawName.Length - maxLength);
            }

            string rawNameKey = rawName.ToLower();

            /*
             * "bin\Release\similarFiles.txt" and "bin\similarfiles.txt" will produce the following IDs
             * "Component.similarFiles.txt" and "Component.similariles.txt", which will be treated by Wix compiler as duplication
             */

            if (!idMaps[entity.GetType()].ContainsSimilarKey(rawName)) //this Type has not been generated yet
            {
                idMaps[entity.GetType()][rawNameKey] = 0;
                entity.id = rawName;
                if (char.IsDigit(entity.id.Last()))
                {
                    entity.id += "_"; // work around for https://wixsharp.codeplex.com/workitem/142
                }
                // to avoid potential collision between ids that end with digit
                // and auto indexed (e.g. [rawName + "." + index])
            }
            else
            {
                //The Id has been already generated for this Type with this rawName
                //so just increase the index
                var index = idMaps[entity.GetType()][rawNameKey] + 1;

                entity.id = rawName + "." + index;
                idMaps[entity.GetType()][rawNameKey] = index;
            }

            //Trace.WriteLine(">>> " + GetType() + " >>> " + id);

            if (rawName.IsNotEmpty() && char.IsDigit(rawName[0]))
            {
                entity.id = "_" + entity.id;
            }

            while (alreadyTakenIds.Contains(entity.id)) //last line of defense against duplication
            {
                entity.id += "_";
            }

            alreadyTakenIds.Add(entity.id);

            return(entity.id);
        }