예제 #1
0
        /// <summary>
        /// Dupms the given Registry data into a file.
        /// </summary>
        public static void DumpInstallationData(InstallationDataXml data, string sRegistryRegistrationDataFile)
        {
            var serializer = new XmlSerializer(typeof(RegistryXml));

            using (var stream = new FileStream(sRegistryRegistrationDataFile, FileMode.Create, FileAccess.Write, FileShare.Read))
                serializer.Serialize(stream, data);
        }
예제 #2
0
 /// <summary>
 /// Collects the one-time global registration data from the attribute installers, one that is not per-attribute or per-assembly.
 /// Invoked from <see cref="InvokeAttributeInstallersInstance"/>, don't call manually.
 /// </summary>
 protected void InvokeAttributeInstallersStatic(InstallationDataXml total)
 {
     foreach (IInstallAttributes installer in MapInstallerTypeToInstance.Values)
     {
         InstallationDataXml data = installer.InstallStatic(this);
         if (data != null)
         {
             total.MergeWith(data);
         }
     }
 }
예제 #3
0
파일: LocalInstaller.cs 프로젝트: mo5h/omeo
        /// <summary>
        /// Copies or deletes the files.
        /// </summary>
        private static void InstallFiles(InstallationDataXml dataxml, RegistrationStage stage, Action <string> LogMessage, Func <SourceRootXml, DirectoryInfo> ResolveSourceDirRoot, Func <TargetRootXml, DirectoryInfo> ResolveTargetDirRoot)
        {
            dataxml.AssertValid();

            foreach (FolderXml folderxml in dataxml.Files)
            {
                var diSource = new DirectoryInfo(Path.Combine(ResolveSourceDirRoot(folderxml.SourceRoot).FullName, folderxml.SourceDir));
                var diTarget = new DirectoryInfo(Path.Combine(ResolveTargetDirRoot(folderxml.TargetRoot).FullName, folderxml.TargetDir));
                diTarget.Create();

                foreach (FileXml filexml in folderxml.Files)
                {
                    FileInfo[] files = diSource.GetFiles(filexml.SourceName);
                    if (files.Length == 0)
                    {
                        throw new InvalidOperationException(string.Format("There are no files matching the “{0}” mask in the source folder “{1}”.", filexml.SourceName, diSource.FullName));
                    }
                    if ((files.Length > 1) && (filexml.TargetName.Length > 0))
                    {
                        throw new InvalidOperationException(string.Format("There are {2} files matching the “{0}” mask in the source folder “{1}”, in which case it's illegal to specify a target name for the file.", filexml.SourceName, diSource.FullName, files.Length));
                    }

                    foreach (FileInfo fiSource in files)
                    {
                        var fiTarget = new FileInfo(Path.Combine(diTarget.FullName, (filexml.TargetName.Length > 0 ? filexml.TargetName : fiSource.Name)));                         // Explicit target name, if present and if a single file; otherwise, use from source

                        // Don't copy and, especially, don't delete the inplace files
                        if (fiSource.FullName == fiTarget.FullName)
                        {
                            LogMessage(string.Format("Skipping “{0}” because source and target are the same file.", fiSource.FullName, fiTarget.FullName));
                            continue;
                        }

                        switch (stage)
                        {
                        case RegistrationStage.Register:
                            LogMessage(string.Format("Installing “{0}” -> “{1}”.", fiSource.FullName, fiTarget.FullName));
                            fiSource.CopyTo(fiTarget.FullName, true);
                            break;

                        case RegistrationStage.Unregister:
                            LogMessage(string.Format("Uninstalling “{0}”.", fiTarget.FullName));
                            fiTarget.Delete();
                            break;

                        default:
                            throw new InvalidOperationException(string.Format("Unexpected stage {0}.", stage));
                        }
                    }
                }
            }
        }
예제 #4
0
        public InstallationDataXml HarvestInstallationData()
        {
            var data = new InstallationDataXml();

            // Run the attribute installers statically (each instance once)
            InvokeAttributeInstallersStatic(data);

            // Run the attribute installers per each attribute instance
            InvokeAttributeInstallersInstance(data);

            data.EnsureNotNull();
            data.RemoveDuplicates();
            data.AssertValid();

            return(data);
        }
예제 #5
0
        /// <summary>
        /// Actions under the resolver.
        /// </summary>
        protected override void ExecuteTaskResolved()
        {
            // Prepare the GUID cache
            myGuidCache = GuidCacheXml.Load(new FileInfo(Bag.GetString(AttributeName.GuidCacheFile)).OpenRead());

            // Global structure of the WiX fragment file
            var wix = new Wix();
            var wixFragmentComponents = new Fragment();             // Fragment with the payload

            wix.AddChild(wixFragmentComponents);
            var wixDirectoryRef = new DirectoryRef();             // Mount into the directories tree, defined externally

            wixFragmentComponents.AddChild(wixDirectoryRef);
            wixDirectoryRef.Id = Bag.GetString(AttributeName.WixDirectoryId);

            var wixFragmentGroup = new Fragment();             // Fragment with the component-group that collects the components

            wix.AddChild(wixFragmentGroup);
            var wixComponentGroup = new ComponentGroup();             // ComponentGroup that collects the components

            wixFragmentGroup.AddChild(wixComponentGroup);
            wixComponentGroup.Id = Bag.GetString(AttributeName.WixComponentGroupId);

            // Get the dump from the product
            InstallationDataXml          dataxml = CreateInstaller().HarvestInstallationData();
            IDictionary <string, string> macros  = GetMacros();

            // Nullref guards
            dataxml.AssertValid();

            // Convert into WiX
            int nProducedFiles  = ConvertFiles(wixDirectoryRef, wixComponentGroup, dataxml, macros);
            int nProducedKeys   = ConvertRegistryKeys(wixDirectoryRef, wixComponentGroup, dataxml, macros);
            int nProducedValues = ConvertRegistryValues(wixDirectoryRef, wixComponentGroup, dataxml, macros);

            // Save to the output file
            using (var xw = new XmlTextWriter(new FileStream(Bag.GetString(AttributeName.OutputFile), FileMode.Create, FileAccess.Write, FileShare.Read), Encoding.UTF8))
            {
                xw.Formatting = Formatting.Indented;
                wix.OutputXml(xw);
            }

            // Report (also to see the target in the build logs)
            Log.LogMessage(MessageImportance.Normal, "Generated {0} files, {1} Registry keys, and {2} Registry values.", nProducedFiles, nProducedKeys, nProducedValues);
        }
예제 #6
0
 protected InstallationDataXml InvokeAttributeInstallersInstance(InstallationDataXml retval)
 {
     // Process each known assembly
     foreach (Assembly assembly in Assemblies)
     {
         // Invoke registration
         try
         {
             foreach (var pair in MapAttributeToInstallers)
             {
                 foreach (object attribute in assembly.GetCustomAttributes(pair.Key, false))
                 {
                     foreach (IInstallAttributes installer in pair.Value)
                     {
                         try
                         {
                             // Collect installation data!
                             InstallationDataXml data = installer.InstallInstance(this, attribute);
                             if (data != null)
                             {
                                 retval.MergeWith(data);
                             }
                         }
                         catch (Exception ex)
                         {
                             throw new InvalidOperationException(string.Format("Failed to collect the installation data for the attribute of type “{0}” from the assembly “{1}” using the “{2}” installer. {3}", pair.Key.AssemblyQualifiedName, assembly.FullName, installer.GetType().AssemblyQualifiedName, ex.Message), ex);
                         }
                     }
                 }
             }
         }
         catch (Exception ex)
         {
             throw new InvalidOperationException(string.Format("Failed to process the “{0}” assembly. {1}", assembly.FullName, ex.Message), ex);
         }
     }
     return(retval);
 }
예제 #7
0
파일: LocalInstaller.cs 프로젝트: mo5h/omeo
 /// <summary>
 /// Performs the local installation of the given installation data by writing the Registry keys and copying the files.
 /// </summary>
 /// <param name="dataxml">The installation data.</param>
 /// <param name="stage">Stage, either install or uninstall.</param>
 /// <param name="LogMessage">The logging facility.</param>
 /// <param name="ResolveSourceDirRoot">Resolves the source directory, for copying the files from.</param>
 /// <param name="ResolveTargetDirRoot">Resolves the target directory, for copying the files into.</param>
 /// <param name="macros">The maros to be substituted on install, if needed.</param>
 public static void Install(InstallationDataXml dataxml, RegistrationStage stage, IDictionary <string, string> macros, Func <SourceRootXml, DirectoryInfo> ResolveSourceDirRoot, Func <TargetRootXml, DirectoryInfo> ResolveTargetDirRoot, Action <string> LogMessage)
 {
     InstallRegistry(dataxml.Registry, stage, macros);
     InstallFiles(dataxml, stage, LogMessage, ResolveSourceDirRoot, ResolveTargetDirRoot);
 }
예제 #8
0
        /// <summary>
        /// Emits WiX Registry Values from the installation data.
        /// </summary>
        private int ConvertRegistryValues(DirectoryRef directory, ComponentGroup componentgroup, InstallationDataXml dataxml, IDictionary <string, string> macros)
        {
            foreach (RegistryValueXml valuexml in dataxml.Registry.Value)
            {
                try
                {
                    var value = new RegistryValue();
                    GetComponentForHive(valuexml.Hive, directory, componentgroup).AddChild(value);
                    value.Root = GetRoot(valuexml.Hive);
                    value.Key  = LocalInstaller.SubstituteMacros(macros, valuexml.Key);
                    if (!string.IsNullOrEmpty(valuexml.Name))                    // The default value name must be Null not an empty string
                    {
                        value.Name = LocalInstaller.SubstituteMacros(macros, valuexml.Name);
                    }
                    value.Value = LocalInstaller.SubstituteMacros(macros, valuexml.Value);
                    value.Type  = GetValueType(valuexml.Type);

                    value.Action = RegistryValue.ActionType.write;
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException(string.Format("Failed to process the value {0}. {1}", valuexml, ex.Message), ex);
                }
            }

            return(dataxml.Registry.Value.Length);
        }
예제 #9
0
        /// <summary>
        /// Emits WiX Registry Keys from the installation data.
        /// </summary>
        private int ConvertRegistryKeys(DirectoryRef directory, ComponentGroup componentgroup, InstallationDataXml dataxml, IDictionary <string, string> macros)
        {
            foreach (RegistryKeyXml keyxml in dataxml.Registry.Key)            // Keys
            {
                try
                {
                    var key = new RegistryKey();
                    GetComponentForHive(keyxml.Hive, directory, componentgroup).AddChild(key);
                    key.Root   = GetRoot(keyxml.Hive);
                    key.Key    = LocalInstaller.SubstituteMacros(macros, keyxml.Key);
                    key.Action = RegistryKey.ActionType.createAndRemoveOnUninstall;
                }
                catch (Exception ex)
                {
                    throw new InvalidOperationException(string.Format("Failed to process the key {0}. {1}", keyxml, ex.Message), ex);
                }
            }

            return(dataxml.Registry.Key.Length);
        }
예제 #10
0
        /// <summary>
        /// Processes the installation files, produces the WiX data.
        /// </summary>
        private int ConvertFiles(DirectoryRef wixDirectoryRef, ComponentGroup wixComponentGroup, InstallationDataXml dataxml, IDictionary <string, string> macros)
        {
            int nProduced = 0;

            // Each installation folder derives a component, regardless of whether there are more files in the same folder, or not
            foreach (FolderXml folderxml in dataxml.Files)
            {
                folderxml.AssertValid();

                // Create the component with the files
                var wixComponent = new Component();
                wixComponent.Id       = string.Format("{0}.{1}", ComponentIdPrefix, folderxml.Id);
                wixComponent.Guid     = folderxml.MsiComponentGuid;
                wixComponent.DiskId   = Bag.Get <int>(AttributeName.DiskId);
                wixComponent.Location = Component.LocationType.local;
                ConvertFiles_AddToDirectory(folderxml, wixComponent, wixDirectoryRef);                 // To the directory structure

                // Add to the feature
                var wixComponentRef = new ComponentRef();
                wixComponentRef.Id = wixComponent.Id;
                wixComponentGroup.AddChild(wixComponentRef);                 // To the feature

                var diSource = new DirectoryInfo(Path.Combine(LocalInstallDataResolved.ResolveSourceDirRoot(folderxml.SourceRoot, Bag), folderxml.SourceDir));
                if (!diSource.Exists)
                {
                    throw new InvalidOperationException(string.Format("The source folder “{0}” does not exist.", diSource.FullName));
                }

                // Add files
                foreach (FileXml filexml in folderxml.Files)
                {
                    filexml.AssertValid();

                    FileInfo[] files = diSource.GetFiles(filexml.SourceName);
                    if (files.Length == 0)
                    {
                        throw new InvalidOperationException(string.Format("There are no files matching the “{0}” mask in the source folder “{1}”.", filexml.SourceName, diSource.FullName));
                    }
                    if ((files.Length > 1) && (filexml.TargetName.Length > 0))
                    {
                        throw new InvalidOperationException(string.Format("There are {2} files matching the “{0}” mask in the source folder “{1}”, in which case it's illegal to specify a target name for the file.", filexml.SourceName, diSource.FullName, files.Length));
                    }

                    foreach (FileInfo fiSource in files)
                    {
                        nProduced++;

                        var wixFile = new File();
                        wixComponent.AddChild(wixFile);
                        wixFile.Id       = string.Format("{0}.{1}.{2}", FileIdPrefix, folderxml.Id, fiSource.Name).Replace('-', '_').Replace(' ', '_'); // Replace chars that are not allowed in the ID
                        wixFile.Name     = filexml.TargetName.Length > 0 ? filexml.TargetName : fiSource.Name;                                          // Explicit target name, if present and if a single file; otherwise, use from source
                        wixFile.Checksum = YesNoType.yes;
                        wixFile.ReadOnly = YesNoType.yes;
                        wixFile.Source   = fiSource.FullName;
                    }
                }
            }

            return(nProduced);
        }