예제 #1
0
        protected override void FinishItemCore()
        {
            if (!Directory.Exists(_folder))
            {
                throw new SwixSemanticException(CurrentLine, $"Directory '{_folder}' does not exists");
            }

            var excludePathRegex = PrepareExcludeRegex();

            if (!_directlySetAttributes.TryGetValue("filter", out string filter))
            {
                filter = "*.*";
            }

            bool withSubfolders = _directlySetAttributes.ContainsKey("withSubfolders") && _directlySetAttributes["withSubfolders"] == "yes";

            var manuallySpecifiedSourcePaths = new HashSet <string>(GatheredComponents.Select(c => Path.GetFullPath(c.SourcePath)), StringComparer.OrdinalIgnoreCase);
            var harvestedComponents          = new List <WixComponent>();
            var folder = Path.GetFullPath(_folder); // eliminates relative parts like a\b\..\b2\c
            var files  = Directory.GetFiles(folder, filter, withSubfolders ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);

            foreach (var filepath in files)
            {
                if (manuallySpecifiedSourcePaths.Contains(filepath))
                {
                    continue;
                }
                int harvestingRootSubstringLength = folder.Length;
                if (filepath[harvestingRootSubstringLength] == '\\')
                {
                    harvestingRootSubstringLength++;
                }
                var relativeToHarvestingRoot = filepath.Substring(harvestingRootSubstringLength);
                if (excludePathRegex.IsMatch(relativeToHarvestingRoot))
                {
                    continue;
                }
                var relativeDir = Path.GetDirectoryName(relativeToHarvestingRoot);
                try
                {
                    var component = WixComponent.FromContext(filepath, CurrentAttributeContext);
                    if (relativeDir != null)
                    {
                        component.TargetDir = component.TargetDir == null
                            ? relativeDir
                            : Path.Combine(component.TargetDir, relativeDir);
                    }

                    harvestedComponents.Add(component);
                }
                catch (SwixItemParsingException e)
                {
                    throw new SwixSemanticException(CurrentLine, $"During harvesting of {filepath} file, exception occurs:\n{e}");
                }
            }

            GatheredComponents.AddRange(harvestedComponents);

            base.FinishItemCore();
        }
예제 #2
0
        public ZipSemanticContext(int line, string archivePath, IAttributeContext context, List <WixComponent> components)
            : base(line, context, components)
        {
            var originalFrom = context.GetInheritedAttribute("from");

            if (originalFrom != null)
            {
                archivePath = Path.Combine(originalFrom, archivePath);
            }

            if (!File.Exists(archivePath))
            {
                throw new SwixSemanticException(line, $"File {archivePath} not found");
            }

            var tmp          = SwixProcessor.TempDir;
            var g            = context.GuidProvider.Get(SwixGuidType.ZipArchive, archivePath.ToLowerInvariant()).ToString("N");
            var unpackedPath = Path.GetFullPath(Path.Combine(tmp, g));

            try
            {
                ZipFile.ExtractToDirectory(archivePath, unpackedPath);
            }
            catch (Exception e)
            {
                throw new SwixSemanticException(line, $"Error while unzipping {archivePath} to {unpackedPath}: {e}");
            }

            context.SetAttributes(new[]
            {
                new AhlAttribute("fromBase", unpackedPath),
                new AhlAttribute("from", null)
            });

            int rootSubstringLength = unpackedPath.Length;

            var files = Directory.GetFiles(unpackedPath);

            foreach (string path in files)
            {
                var component = WixComponent.FromContext(path, context);
                if (path[rootSubstringLength] == '\\')
                {
                    rootSubstringLength++;
                }
                var relativeDir = Path.GetDirectoryName(path.Substring(rootSubstringLength));
                if (relativeDir != null)
                {
                    component.TargetDir = component.TargetDir == null
                        ? relativeDir
                        : Path.Combine(component.TargetDir, relativeDir);
                }

                GatheredComponents.Add(component);
            }
        }
예제 #3
0
        private string GetComponentId(WixComponent component)
        {
            if (component.Id != null)
            {
                return(component.Id);
            }
            var guid = _guidProvider.Get(SwixGuidType.Component, GetComponentFullTargetPath(component));

            return(component.Id = MakeUniqueId(guid, component.FileName, MaxIdLength));
        }
예제 #4
0
        private string GetComponentFullTargetPath(WixComponent component)
        {
            if (component.TargetDir != null)
            {
                throw new InvalidOperationException("This method should not be called before handling inline targetDirs");
            }
            var dir = _directories[component.TargetDirRef];

            return($"{dir.GetFullTargetPath()}\\{component.FileName}");
        }
예제 #5
0
        private void WritePermissionElement(XmlWriter doc, WixComponent component)
        {
            var path = GetComponentFullTargetPath(component);
            var guid = _guidProvider.Get(SwixGuidType.SddlPermission, path);
            var id   = MakeUniqueId(guid, component.FileName, MaxIdLength);

            doc.WriteStartElement("PermissionEx");
            doc.WriteAttributeString("Id", id);
            doc.WriteAttributeString("Sddl", component.Sddl);
            doc.WriteEndElement();
        }
예제 #6
0
        private void WriteComponentServices(XmlWriter doc, WixComponent component)
        {
            foreach (var service in component.Services)
            {
                doc.WriteStartElement("ServiceInstall");
                if (service.Id == null)
                {
                    var guid = _guidProvider.Get(SwixGuidType.ServiceInstall, service.Name);
                    service.Id = MakeUniqueId(guid, service.Name, MaxIdLength);
                }

                doc.WriteAttributeString("Id", service.Id);
                doc.WriteAttributeString("Name", service.Name);
                doc.WriteAttributeString("DisplayName", service.DisplayName ?? service.Name);
                if (service.Description != null)
                {
                    doc.WriteAttributeString("Description", service.Description);
                }

                if (service.Account != null)
                {
                    doc.WriteAttributeString("Account", service.Account);
                }

                if (service.Password != null)
                {
                    doc.WriteAttributeString("Password", service.Password);
                }

                var startupType = (service.Start != ServiceStartupType.Unset ? service.Start : ServiceStartupType.Auto).ToString();
                doc.WriteAttributeString("Start", ToCamelCase(startupType));

                var hostingType = (service.Type != ServiceHostingType.Unset ? service.Type : ServiceHostingType.OwnProcess).ToString();
                doc.WriteAttributeString("Type", ToCamelCase(hostingType));

                var errControl = (service.ErrorControl != ServiceErrorControl.Unset ? service.ErrorControl : ServiceErrorControl.Ignore).ToString();
                doc.WriteAttributeString("ErrorControl", ToCamelCase(errControl));

                if (service.Args != null)
                {
                    doc.WriteAttributeString("Arguments", service.Args);
                }

                if (service.Vital != null)
                {
                    doc.WriteAttributeString("Vital", service.Vital);
                }

                doc.WriteEndElement();
            }
        }
예제 #7
0
 public virtual ISemanticContext Component(string key, IAttributeContext itemContext)
 {
     try
     {
         var component           = WixComponent.FromContext(key, itemContext);
         var itemSemanticContext = new ComponentItem(CurrentLine, CurrentAttributeContext, component);
         itemSemanticContext.OnFinished += (s, e) => _toAdd.Add(component);
         return(itemSemanticContext);
     }
     catch (SwixSemanticException e)
     {
         throw new SwixSemanticException(CurrentLine, e.Message);
     }
 }
예제 #8
0
        private void WriteComponent(XmlWriter doc, WixComponent component)
        {
            doc.WriteStartElement("Component");
            var id = GetComponentId(component);

            doc.WriteAttributeString("Id", id);
            if (component.MultiInstance != null)
            {
                doc.WriteAttributeString("MultiInstance", component.MultiInstance);
            }
            if (component.Win64 != null)
            {
                doc.WriteAttributeString("Win64", component.Win64);
            }
            var componentGuid = _guidProvider.Get(SwixGuidType.Component, GetComponentFullTargetPath(component));

            doc.WriteAttributeString("Guid", componentGuid.ToString("B").ToUpperInvariant());

            if (component.Condition != null)
            {
                doc.WriteStartElement("Condition");
                doc.WriteCData(component.Condition);
                doc.WriteEndElement();
            }

            doc.WriteStartElement("File");
            doc.WriteAttributeString("Id", id);
            doc.WriteAttributeString("KeyPath", "yes");
            doc.WriteAttributeString("Source", component.SourcePath);
            doc.WriteAttributeString("Name", component.FileName);

            if (component.CabFileRef != null)
            {
                doc.WriteAttributeString("DiskId", _cabFileCounters[component.CabFileRef].GetNextId().ToString(CultureInfo.InvariantCulture));
            }

            if (component.Sddl != null)
            {
                WritePermissionElement(doc, component);
            }

            WriteComponentShortcuts(doc, component);

            doc.WriteEndElement();

            WriteComponentServices(doc, component);

            doc.WriteEndElement();
        }
예제 #9
0
        public override ISemanticContext Component(string key, IAttributeContext itemContext)
        {
            // we can't allow here non-rooted paths or paths with wix variables, because in this case
            // we won't be able to identify which harvested component we should replace with manually
            // specified one.
            // So, here is the check that SourcePath of resulting component is full, such file exists etc
            var fullPath         = WixComponent.GetFullSourcePath(key, itemContext);
            var invalidPathChars = Path.GetInvalidPathChars();

            if (fullPath.IndexOfAny(invalidPathChars) != -1)
            {
                throw new SwixSemanticException(CurrentLine, "Components inside ?harvest meta should reference existing files without WIX variables.");
            }
            if (!File.Exists(fullPath))
            {
                throw new SwixSemanticException(CurrentLine, $"File {fullPath} is not found. Components inside ?harvest meta should reference existing files without WIX variables.");
            }
            return(base.Component(key, itemContext));
        }
예제 #10
0
 private void WriteComponentShortcuts(XmlWriter doc, WixComponent component)
 {
     foreach (var shortcut in component.Shortcuts)
     {
         doc.WriteStartElement("Shortcut");
         var fullPath = $"{_directories[shortcut.TargetDirRef].GetFullTargetPath()}\\{shortcut.Name}";
         var guid     = _guidProvider.Get(SwixGuidType.Shortcut, fullPath);
         var id       = MakeUniqueId(guid, shortcut.Name, MaxIdLength);
         doc.WriteAttributeString("Id", id);
         doc.WriteAttributeString("Name", shortcut.Name);
         if (shortcut.Args != null)
         {
             doc.WriteAttributeString("Arguments", shortcut.Args);
         }
         if (shortcut.WorkingDir != null)
         {
             doc.WriteAttributeString("WorkingDirectory", shortcut.WorkingDir);
         }
         doc.WriteAttributeString("Advertise", "yes");
         doc.WriteAttributeString("Directory", shortcut.TargetDirRef);
         doc.WriteEndElement();
     }
 }
예제 #11
0
 public ComponentItem(int line, IAttributeContext inheritedContext, WixComponent component)
     : base(line, inheritedContext)
 {
     _component = component;
 }
예제 #12
0
        public static WixComponent FromContext(string key, IAttributeContext context)
        {
            var result = new WixComponent(GetFullSourcePath(key, context));

            var fileName = context.GetInheritedAttribute("name");

            if (fileName != null)
            {
                result.FileName = fileName;
            }
            else
            {
                var idx = key.LastIndexOf('\\');
                result.FileName = key.Substring(idx + 1);
            }

            var targetDirRef = context.GetInheritedAttribute("targetDirRef");

            if (targetDirRef != null)
            {
                result.TargetDirRef = targetDirRef;
            }
            else
            {
                throw new SwixItemParsingException("targetDirRef attribute is mandatory for all components");
            }

            var targetDir = context.GetInheritedAttribute("targetDir");

            if (targetDir != null)
            {
                result.TargetDir = targetDir;
            }

            var cabFileRef = context.GetInheritedAttribute("cabFileRef");

            if (cabFileRef != null)
            {
                result.CabFileRef = cabFileRef;
            }

            var moduleRef = context.GetInheritedAttribute("moduleRef");

            if (moduleRef != null)
            {
                result.ModuleRef = moduleRef;
            }

            if (cabFileRef == null && moduleRef == null)
            {
                throw new SwixItemParsingException("cabFileRef or moduleRef attribute is mandatory for all components");
            }

            if (cabFileRef != null && moduleRef != null)
            {
                throw new SwixItemParsingException("You can't specify both cabFileRef and moduleRef for same component");
            }

            result.OutputTag = context.GetInheritedAttribute("outputTag");
            result.Condition = context.GetInheritedAttribute("condition");

            var componentGroupRef = context.GetInheritedAttribute("componentGroupRef");

            if (componentGroupRef != null)
            {
                result.ComponentGroupRef = componentGroupRef;
            }

            var multiInstance = context.GetInheritedAttribute("multiInstance");

            if (multiInstance != "yes" && multiInstance != "no" && multiInstance != null)
            {
                throw new SwixItemParsingException("Optional 'multiInstance' attribute could be only 'yes' or 'no'");
            }
            result.MultiInstance = multiInstance;

            var win64 = context.GetInheritedAttribute("win64");

            if (win64 != "yes" && win64 != "no" && win64 != null)
            {
                throw new SwixItemParsingException("Optional 'win64' attribute could be only 'yes' or 'no'");
            }
            result.Win64 = win64;

            var id = context.GetInheritedAttribute("id");

            if (id != null)
            {
                result.Id = id;
            }

            var sddl = context.GetInheritedAttribute("sddl");

            if (sddl != null)
            {
                result.Sddl = sddl;
            }

            return(result);
        }