public void TestDisplayCab()
        {
            Console.WriteLine("TestDisplayCab");

            // create a self-extracting bootstrapper
            ConfigFile configFile = new ConfigFile();
            SetupConfiguration setupConfiguration = new SetupConfiguration();
            configFile.Children.Add(setupConfiguration);
            InstallerLinkerArguments args = new InstallerLinkerArguments();
            args.config = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".xml");
            Console.WriteLine("Writing '{0}'", args.config);
            configFile.SaveAs(args.config);
            args.embed = true;
            args.apppath = Path.GetTempPath();
            // args.embedFiles = new string[] { Path.GetFileName(args.config) };
            args.output = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".exe");
            args.template = dotNetInstallerExeUtils.Executable;
            Console.WriteLine("Linking '{0}'", args.output);
            InstallerLinkerExeUtils.CreateInstaller(args);
            Assert.IsTrue(File.Exists(args.output));
            // execute dotNetInstaller
            Assert.AreEqual(0, dotNetInstallerExeUtils.Run(args.output, "/DisplayCab /qb"));
            File.Delete(args.config);
            File.Delete(args.output);
        }
        public static int Main(string[] args)
        {
            int rc = 0;

            Console.WriteLine("InstallerLinker: dotNetInstaller Packager ({0})", Assembly.GetExecutingAssembly().GetName().Version);
            Console.WriteLine();

            InstallerLinkerArguments i_args = new InstallerLinkerArguments();
            if (Parser.ParseArgumentsWithUsage(args, i_args))
            {
                try
                {
                    InstallerLib.InstallerLinker.CreateInstaller(i_args);
                }
                catch (Exception ex)
                {
                    i_args.WriteError(string.Format("ERROR: {0}", ex.Message));
#if DEBUG
                    i_args.WriteError(ex.StackTrace);
#endif
                    rc = -2;
                }
            }
            else
            {
                rc = -1;
            }

            return rc;
        }
        /// <summary>
        /// Check whether all embedded files exist.
        /// </summary>
        /// <param name="args"></param>
        public void CheckFilesExist(InstallerLinkerArguments args)
        {
            List <String> filesMissing = new List <string>();

            foreach (EmbedFilePair file in _files)
            {
                args.WriteLine(string.Format(" {0} ({1})", file.fullpath, file.relativepath));
                if (!File.Exists(file.fullpath))
                {
                    string fullpath = Path.GetFullPath(file.fullpath);
                    args.WriteError(string.Format("Embedded file '{0}' does not exist", fullpath));
                    filesMissing.Add(fullpath);
                }
            }

            if (filesMissing.Count > 0)
            {
                StringBuilder sb  = new StringBuilder();
                int           max = 5;
                sb.AppendLine(string.Format("Missing {0} embedded file(s)", filesMissing.Count));
                for (int i = 0; i < max && i < filesMissing.Count; i++)
                {
                    sb.AppendLine(filesMissing[i]);
                }
                if (filesMissing.Count > max)
                {
                    sb.AppendLine("...");
                }
                throw new Exception(sb.ToString());
            }
        }
 public static void CreateInstaller(InstallerLinkerArguments args)
 {
     List<String> cmd = new List<string>();
     cmd.Add(string.Format("/Configuration:\"{0}\"", args.config));
     cmd.Add(string.Format("/Template:\"{0}\"", dotNetInstallerExeUtils.Executable));
     cmd.Add(string.Format("/Output:\"{0}\"", args.output));
     if (!string.IsNullOrEmpty(args.apppath))
     {
         cmd.Add(string.Format("/AppPath:\"{0}\"", args.apppath.TrimEnd("\\".ToCharArray())));
     }
     if (args.verbose) cmd.Add("/Verbose+");
     if (args.embed) cmd.Add("/Embed+");
     if (args.embedFiles != null)
     {
         foreach (string file in args.embedFiles)
             cmd.Add(string.Format("/EmbedFile:\"{0}\"", file));
     }
     if (args.embedFolders != null)
     {
         foreach (string folder in args.embedFolders)
             cmd.Add(string.Format("/EmbedFolder:\"{0}\"", folder));
     }
     if (args.htmlFiles != null)
     {
         foreach (string folder in args.htmlFiles)
             cmd.Add(string.Format("/EmbedHtml:\"{0}\"", folder));
     }
     Run(InstallerLinkerExeUtils.Executable, string.Join(" ", cmd.ToArray()));
 }
 /// <summary>
 /// Checks file attributes and warns the user if any are read-only.
 /// </summary>
 /// <param name="args"></param>
 public void CheckFileAttributes(InstallerLinkerArguments args)
 {
     foreach (EmbedFilePair file in _files)
     {
         if ((File.GetAttributes(file.fullpath) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
         {
             args.WriteLine(string.Format("Embedded file '{0}' is and will be extracted read-only.", file.fullpath));
         }
     }
 }
        public void TestEmbedSplashScreen()
        {
            InstallerLinkerArguments args = new InstallerLinkerArguments();
            try
            {
                Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase);
                string binPath = Path.GetDirectoryName(HttpUtility.UrlDecode(uri.AbsolutePath));
                ConfigFile configFile = new ConfigFile();
                SetupConfiguration setupConfiguration = new SetupConfiguration();
                configFile.Children.Add(setupConfiguration);
                ComponentCmd cmd = new ComponentCmd();
                cmd.command = "cmd.exe /C exit /b 0";
                setupConfiguration.Children.Add(cmd);
                args.config = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".xml");
                Console.WriteLine("Writing '{0}'", args.config);
                configFile.SaveAs(args.config);
                args.output = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".exe");
                Console.WriteLine("Linking '{0}'", args.output);
                args.template = dotNetInstallerExeUtils.Executable;

                string relativePathName = "res";
                bool usingHtmlInstaller = dotNetInstallerExeUtils.Executable.EndsWith("htmlInstaller.exe");
                if (usingHtmlInstaller)
                {
                    relativePathName = "Html";
                }

                args.splash = Path.Combine(dotNetInstallerExeUtils.Location, string.Format(@"..\{0}\banner.bmp", relativePathName));
                InstallerLib.InstallerLinker.CreateInstaller(args);
                // check that the linker generated output
                Assert.IsTrue(File.Exists(args.output));
                Assert.IsTrue(new FileInfo(args.output).Length > 0);
                using (ResourceInfo ri = new ResourceInfo())
                {
                    ri.Load(args.output);
                    Assert.IsTrue(ri.Resources.ContainsKey(new ResourceId("CUSTOM")));
                    List<Resource> custom = ri.Resources[new ResourceId("CUSTOM")];
                    Assert.AreEqual("RES_BANNER", custom[0].Name.Name);
                    Assert.AreEqual("RES_CONFIGURATION", custom[1].Name.ToString());
                    Assert.AreEqual("RES_SPLASH", custom[2].Name.ToString());
                }
                // execute with and without splash
                dotNetInstallerExeUtils.Run(args.output, "/qb");
                dotNetInstallerExeUtils.Run(args.output, "/qb /nosplash");
            }
            finally
            {
                if (File.Exists(args.config))
                    File.Delete(args.config);
                if (File.Exists(args.output))
                    File.Delete(args.output);
            }
        }
 public void TestControlLicenseResources()
 {
     InstallerLinkerArguments args = new InstallerLinkerArguments();
     string licenseFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".txt");
     try
     {
         Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase);
         string binPath = Path.GetDirectoryName(HttpUtility.UrlDecode(uri.AbsolutePath));
         ConfigFile configFile = new ConfigFile();
         SetupConfiguration setupConfiguration = new SetupConfiguration();
         configFile.Children.Add(setupConfiguration);
         ControlLicense license = new ControlLicense();
         license.LicenseFile = licenseFile;
         Console.WriteLine("Writing '{0}'", license.LicenseFile);
         File.WriteAllText(license.LicenseFile, "Lorem ipsum");
         setupConfiguration.Children.Add(license);
         args.config = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".xml");
         Console.WriteLine("Writing '{0}'", args.config);
         configFile.SaveAs(args.config);
         args.output = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".exe");
         Console.WriteLine("Linking '{0}'", args.output);
         args.template = dotNetInstallerExeUtils.Executable;
         InstallerLib.InstallerLinker.CreateInstaller(args);
         // check that the linker generated output
         Assert.IsTrue(File.Exists(args.output));
         Assert.IsTrue(new FileInfo(args.output).Length > 0);
         using (ResourceInfo ri = new ResourceInfo())
         {
             ri.Load(args.output);
             Assert.IsTrue(ri.Resources.ContainsKey(new ResourceId("CUSTOM")));
             List<Resource> custom = ri.Resources[new ResourceId("CUSTOM")];
             Assert.AreEqual("RES_BANNER", custom[0].Name.Name);
             Assert.AreEqual("RES_CONFIGURATION", custom[1].Name.ToString());
             Assert.AreEqual("RES_LICENSE", custom[2].Name.ToString());
         }
     }
     finally
     {
         if (File.Exists(licenseFile))
             File.Delete(licenseFile);
         if (File.Exists(args.config))
             File.Delete(args.config);
         if (File.Exists(args.output))
             File.Delete(args.output);
     }
 }
        /// <summary>
        /// Check whether all embedded files exist.
        /// </summary>
        /// <param name="args"></param>
        public void CheckFilesExist(InstallerLinkerArguments args)
        {
            int filesMissing = 0;

            foreach (ResourceFilePair file in _files)
            {
                args.WriteLine(string.Format(" {0} ({1})", file.id, file.path));
                if (!File.Exists(file.path))
                {
                    args.WriteError(string.Format("Resource file '{0}' does not exist", file.path));
                    filesMissing++;
                }
            }

            if (filesMissing > 0)
            {
                throw new Exception(string.Format("Missing {0} resource file(s)",
                                                  filesMissing));
            }
        }
        public void TestExtractAndRunCabPerComponent()
        {
            Console.WriteLine("TestExtractAndRunCabPerComponent");

            InstallerLinkerArguments args = new InstallerLinkerArguments();
            args.config = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".xml");
            Console.WriteLine("Writing '{0}'", args.config);
            args.embed = true;
            args.apppath = Path.GetTempPath();
            args.output = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".exe");
            args.template = dotNetInstallerExeUtils.Executable;
            // create a self-extracting bootstrapper
            ConfigFile configFile = new ConfigFile();
            SetupConfiguration setupConfiguration = new SetupConfiguration();
            setupConfiguration.cab_path = Path.Combine(Path.GetTempPath(), "testExtractAndRunCabPerComponent");
            setupConfiguration.cab_path_autodelete = false;
            configFile.Children.Add(setupConfiguration);
            ComponentCmd component = new ComponentCmd();
            component.command = "cmd.exe /C copy \"#CABPATH\\component\\before.xml\" \"#CABPATH\\component\\after.xml\"";
            component.required_install = true;
            setupConfiguration.Children.Add(component);
            EmbedFile embedfile = new EmbedFile();
            embedfile.sourcefilepath = args.config;
            embedfile.targetfilepath = @"component\before.xml";
            component.Children.Add(embedfile);
            configFile.SaveAs(args.config);
            Console.WriteLine("Linking '{0}'", args.output);
            InstallerLinkerExeUtils.CreateInstaller(args);
            Assert.IsTrue(File.Exists(args.output));
            // execute dotNetInstaller
            string logfile = Path.Combine(Path.GetTempPath(), "testExtractAndRunCabPerComponent.log");
            Console.WriteLine("Log: {0}", logfile);
            Assert.AreEqual(0, dotNetInstallerExeUtils.Run(args.output, string.Format("/qb /log /logfile \"{0}\"", logfile)));
            string extractedComponentPath = Path.Combine(setupConfiguration.cab_path, "component");
            Console.WriteLine("Checking {0}", extractedComponentPath);
            Assert.IsTrue(Directory.Exists(extractedComponentPath), string.Format("Missing {0}", extractedComponentPath));
            Assert.IsTrue(File.Exists(Path.Combine(Path.GetTempPath(), @"testExtractAndRunCabPerComponent\component\before.xml")));
            Assert.IsTrue(File.Exists(Path.Combine(Path.GetTempPath(), @"testExtractAndRunCabPerComponent\component\after.xml")));
            File.Delete(args.config);
            File.Delete(args.output);
            Directory.Delete(setupConfiguration.cab_path, true);
            File.Delete(logfile);
        }
        public void TestUserControlLicense()
        {
            Console.WriteLine("TestUserControlLicense");

            string configFilename = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".xml");
            // a configuration with a license agreement control
            ConfigFile configFile = new ConfigFile();
            SetupConfiguration setupConfiguration = new SetupConfiguration();
            configFile.Children.Add(setupConfiguration);
            ControlLicense license = new ControlLicense();
            license.Accepted = true;
            license.ResourceId = "MY_RES_LICENSE";
            license.LicenseFile = configFilename;
            setupConfiguration.Children.Add(license);
            ComponentCmd cmd = new ComponentCmd();
            cmd.command = "cmd.exe /C exit /b [MY_RES_LICENSE]";
            cmd.required_install = true;
            setupConfiguration.Children.Add(cmd);
            // save config file
            Console.WriteLine("Writing '{0}'", configFilename);
            configFile.SaveAs(configFilename);
            // create a setup with the license file
            InstallerLinkerArguments args = new InstallerLinkerArguments();
            args.config = configFilename;
            args.output = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".exe");
            args.template = dotNetInstallerExeUtils.Executable;
            Console.WriteLine("Linking '{0}'", args.output);
            InstallerLinkerExeUtils.CreateInstaller(args);
            Assert.IsTrue(File.Exists(args.output));
            // execute dotNetInstaller
            Assert.AreEqual(1, dotNetInstallerExeUtils.Run(args.output, "/q"));
            File.Delete(args.config);
            File.Delete(args.output);
        }
Example #11
0
        private void btMake_Click(object sender, System.EventArgs e)
        {
            try
            {
                if (!System.IO.File.Exists(txtTemplateFile.Text))
                    throw new ApplicationException("Template file '" + txtTemplateFile.Text + "' is missing");

                if (!System.IO.File.Exists(ConfigFile))
                    throw new ApplicationException("Configuration file '" + ConfigFile + " ' is missing");

                SaveFileDialog l_dg = new SaveFileDialog();
                l_dg.FileName = m_OutputFileName;
                l_dg.Filter = "Exe File (*.exe)|*.exe|All Files(*.*)|*.*";
                l_dg.DefaultExt = "exe";
                if (l_dg.ShowDialog(this) == DialogResult.OK)
                {
                    InstallerLinkerArguments args = new InstallerLinkerArguments();
                    args.banner = txtBannerBitmap.Text;
                    args.icon = txtIcon.Text;
                    args.config = ConfigFile;
                    args.output = l_dg.FileName;
                    args.template = txtTemplateFile.Text;
                    args.embed = chkEmbed.Checked;
                    args.manifest = txtManifest.Text;
                    args.splash = txtSplashBitmap.Text;
                    InstallerLinker.CreateInstaller(args);
                    m_OutputFileName = l_dg.FileName;
                    DialogResult = DialogResult.OK;
                    Close();
                }
            }
            catch (Exception err)
            {
                AppUtility.ShowError(this, err);
            }
        }
 public void TestLinkUnicows()
 {
     InstallerLinkerArguments args = new InstallerLinkerArguments();
     try
     {
         ConfigFile configFile = new ConfigFile();
         SetupConfiguration setupConfiguration = new SetupConfiguration();
         configFile.Children.Add(setupConfiguration);
         args.config = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".xml");
         Console.WriteLine("Writing '{0}'", args.config);
         configFile.SaveAs(args.config);
         args.output = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".exe");
         Console.WriteLine("Linking '{0}'", args.output);
         args.template = dotNetInstallerExeUtils.Executable;
         args.mslu = true;
         InstallerLib.InstallerLinker.CreateInstaller(args);
         // check that the linker generated output
         Assert.IsTrue(File.Exists(args.output));
         Assert.IsTrue(new FileInfo(args.output).Length > 0);
         using (ResourceInfo ri = new ResourceInfo())
         {
             ri.Load(args.output);
             List<Resource> custom = ri.Resources[new ResourceId("CUSTOM")];
             Assert.IsNotNull(custom);
             Assert.AreEqual(3, custom.Count);
             // default banner
             Assert.AreEqual(custom[0].Name, new ResourceId("RES_BANNER"));
             // embedded configuration
             Assert.AreEqual(custom[1].Name, new ResourceId("RES_CONFIGURATION"));
             Assert.AreEqual(custom[1].Size, new FileInfo(args.config).Length);
             // unicows
             Assert.AreEqual(custom[2].Name, new ResourceId("RES_UNICOWS"));
         }
     }
     finally
     {
         if (File.Exists(args.config))
             File.Delete(args.config);
         if (File.Exists(args.output))
             File.Delete(args.output);
     }
 }
 public void TestLinkProcessorArchitectureFilter()
 {
     // configurations
     SetupConfiguration nofilterConfiguration = new SetupConfiguration();
     SetupConfiguration x86Configuration = new SetupConfiguration();
     x86Configuration.processor_architecture_filter = "x86";
     SetupConfiguration x64Configuration = new SetupConfiguration();
     x64Configuration.processor_architecture_filter = "x64";
     SetupConfiguration mipsConfiguration = new SetupConfiguration();
     mipsConfiguration.processor_architecture_filter = "mips";
     // components
     ComponentCmd nofilterComponent = new ComponentCmd();
     ComponentCmd x86Component = new ComponentCmd();
     x86Component.processor_architecture_filter = "x86";
     ComponentCmd x64Component = new ComponentCmd();
     x64Component.processor_architecture_filter = "x64";
     ComponentCmd mipsComponent = new ComponentCmd();
     mipsComponent.processor_architecture_filter = "mips";
     // make a tree
     nofilterConfiguration.Children.Add(nofilterComponent);
     nofilterConfiguration.Children.Add(x86Component);
     nofilterConfiguration.Children.Add(x64Component);
     nofilterConfiguration.Children.Add(mipsComponent);
     x86Configuration.Children.Add(nofilterComponent);
     x86Configuration.Children.Add(x86Component);
     x86Configuration.Children.Add(x64Component);
     x86Configuration.Children.Add(mipsComponent);
     x64Configuration.Children.Add(nofilterComponent);
     x64Configuration.Children.Add(x86Component);
     x64Configuration.Children.Add(x64Component);
     x64Configuration.Children.Add(mipsComponent);
     mipsConfiguration.Children.Add(nofilterComponent);
     mipsConfiguration.Children.Add(x86Component);
     mipsConfiguration.Children.Add(x64Component);
     mipsConfiguration.Children.Add(mipsComponent);
     // configfile
     ConfigFile configFile = new ConfigFile();
     configFile.Children.Add(nofilterConfiguration);
     configFile.Children.Add(x86Configuration);
     configFile.Children.Add(x64Configuration);
     configFile.Children.Add(mipsConfiguration);
     // write a configuration
     InstallerLinkerArguments args = new InstallerLinkerArguments();
     args.processorArchitecture = "x86,alpha";
     args.config = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".xml");
     args.output = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".exe");
     Console.WriteLine("Writing '{0}'", args.config);
     try
     {
         configFile.SaveAs(args.config);
         Console.WriteLine("Linking '{0}'", args.output);
         args.template = dotNetInstallerExeUtils.Executable;
         InstallerLib.InstallerLinker.CreateInstaller(args);
         // check that the linker generated output
         Assert.IsTrue(File.Exists(args.output));
         Assert.IsTrue(new FileInfo(args.output).Length > 0);
         using (ResourceInfo ri = new ResourceInfo())
         {
             ri.Load(args.output);
             List<Resource> custom = ri.Resources[new ResourceId("CUSTOM")];
             Assert.AreEqual(custom[1].Name, new ResourceId("RES_CONFIGURATION"));
             byte[] data = custom[1].WriteAndGetBytes();
             // skip BOM
             String config = Encoding.UTF8.GetString(data, 3, data.Length - 3);
             XmlDocument xmldoc = new XmlDocument();
             xmldoc.LoadXml(config);
             ConfigFile filteredConfig = new ConfigFile();
             filteredConfig.LoadXml(xmldoc);
             Assert.AreEqual(2, filteredConfig.ConfigurationCount);
             Assert.AreEqual(4, filteredConfig.ComponentCount);
         }
     }
     finally
     {
         if (File.Exists(args.config))
             File.Delete(args.config);
         if (File.Exists(args.output))
             File.Delete(args.output);
     }
 }
 public void TestLinkNoEmbedFilesAndFolders()
 {
     InstallerLinkerArguments args = new InstallerLinkerArguments();
     try
     {
         Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase);
         string binPath = Path.GetDirectoryName(HttpUtility.UrlDecode(uri.AbsolutePath));
         ConfigFile configFile = new ConfigFile();
         SetupConfiguration setupConfiguration = new SetupConfiguration();
         configFile.Children.Add(setupConfiguration);
         args.config = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".xml");
         Console.WriteLine("Writing '{0}'", args.config);
         configFile.SaveAs(args.config);
         args.output = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".exe");
         Console.WriteLine("Linking '{0}'", args.output);
         args.template = dotNetInstallerExeUtils.Executable;
         args.embedFolders = new string[] { binPath };
         args.embed = false;
         args.embedResourceSize = 0;
         InstallerLib.InstallerLinker.CreateInstaller(args);
         // check that the linker generated output
         Assert.IsTrue(File.Exists(args.output));
         Assert.IsTrue(new FileInfo(args.output).Length > 0);
         using (ResourceInfo ri = new ResourceInfo())
         {
             ri.Load(args.output);
             Assert.IsFalse(ri.Resources.ContainsKey(new ResourceId("RES_CAB")));
         }
     }
     finally
     {
         if (File.Exists(args.config))
             File.Delete(args.config);
         if (File.Exists(args.output))
             File.Delete(args.output);
     }
 }
        public void TestLinkEmbedManifest()
        {
            InstallerLinkerArguments args = new InstallerLinkerArguments();
            try
            {
                ConfigFile configFile = new ConfigFile();
                SetupConfiguration setupConfiguration = new SetupConfiguration();
                configFile.Children.Add(setupConfiguration);
                args.config = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".xml");
                Console.WriteLine("Writing '{0}'", args.config);
                configFile.SaveAs(args.config);
                args.output = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".exe");
                Console.WriteLine("Linking '{0}'", args.output);
                args.template = dotNetInstallerExeUtils.Executable;
                // manifest
                Uri uri = new Uri(Assembly.GetExecutingAssembly().CodeBase);
                args.manifest = Path.Combine(Path.GetDirectoryName(HttpUtility.UrlDecode(uri.AbsolutePath)), "Manifests\\asInvoker.manifest");
                // link
                InstallerLib.InstallerLinker.CreateInstaller(args);
                // check that the linker generated output
                Assert.IsTrue(File.Exists(args.output));
                Assert.IsTrue(new FileInfo(args.output).Length > 0);
                using (ResourceInfo ri = new ResourceInfo())
                {
                    ri.Load(args.output);
                    List<Resource> manifests = ri.Resources[new ResourceId(Kernel32.ResourceTypes.RT_MANIFEST)]; // RT_MANIFEST
                    Assert.IsNotNull(manifests);

                    int expectedManifestFiles = 1;
                    bool usingHtmlInstaller = dotNetInstallerExeUtils.Executable.EndsWith("htmlInstaller.exe");
                    if (usingHtmlInstaller)
                    {
                        // the stub file already has an embedded manifest
                        expectedManifestFiles++;
                    }

                    Assert.AreEqual(expectedManifestFiles, manifests.Count);
                    ManifestResource manifest = (ManifestResource)manifests[0]; // RT_MANIFEST
                    Console.WriteLine(manifest.Manifest.OuterXml);
                    XmlNamespaceManager manifestNamespaceManager = new XmlNamespaceManager(manifest.Manifest.NameTable);
                    manifestNamespaceManager.AddNamespace("v1", "urn:schemas-microsoft-com:asm.v1");
                    manifestNamespaceManager.AddNamespace("v3", "urn:schemas-microsoft-com:asm.v3");
                    string level = manifest.Manifest.SelectSingleNode("//v3:requestedExecutionLevel",
                        manifestNamespaceManager).Attributes["level"].Value;
                    Assert.AreEqual(level, "asInvoker");
                }
            }
            finally
            {
                if (File.Exists(args.config))
                    File.Delete(args.config);
                if (File.Exists(args.output))
                    File.Delete(args.output);
            }
        }
Example #16
0
        public static void CreateInstaller(InstallerLinkerArguments args)
        {
            args.Validate();

            args.WriteLine(string.Format("Creating \"{0}\" from \"{1}\"", args.output, args.template));
            System.IO.File.Copy(args.template, args.output, true);
            System.IO.File.SetAttributes(args.output, System.IO.FileAttributes.Normal);

            string configFilename = args.config;

            #region Version Information

            ConfigFile configfile = new ConfigFile();
            configfile.Load(configFilename);

            // \todo: check XML with XSD, warn if nodes are being dropped

            // filter the configuration
            string configTemp = null;
            if (!string.IsNullOrEmpty(args.processorArchitecture))
            {
                int configurationCount = configfile.ConfigurationCount;
                int componentCount = configfile.ComponentCount;
                args.WriteLine(string.Format("Applying processor architecture filter \"{0}\"", args.processorArchitecture));
                ProcessorArchitectureFilter filter = new ProcessorArchitectureFilter(args.processorArchitecture);
                XmlDocument filteredXml = configfile.GetXml(filter);
                configTemp = configFilename = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
                filteredXml.Save(configTemp);
                configfile.LoadXml(filteredXml);
                args.WriteLine(string.Format(" configurations: {0} => {1}", configurationCount, configfile.ConfigurationCount));
                args.WriteLine(string.Format(" components: {0} => {1}", componentCount, configfile.ComponentCount));
            }

            args.WriteLine(string.Format("Updating binary attributes in \"{0}\"", args.output));
            VersionResource rc = new VersionResource();
            rc.LoadFrom(args.output);

            // version information
            StringFileInfo stringFileInfo = (StringFileInfo)rc["StringFileInfo"];
            if (!string.IsNullOrEmpty(configfile.productversion))
            {
                rc.ProductVersion = configfile.productversion;
                stringFileInfo["ProductVersion"] = configfile.productversion;
            }

            if (!string.IsNullOrEmpty(configfile.fileversion))
            {
                rc.FileVersion = configfile.fileversion;
                stringFileInfo["FileVersion"] = configfile.fileversion;
            }

            foreach (FileAttribute attr in configfile.fileattributes)
            {
                args.WriteLine(string.Format(" {0}: {1}", attr.name, attr.value));
                stringFileInfo[attr.name] = attr.value;
            }

            rc.Language = ResourceUtil.NEUTRALLANGID;
            rc.SaveTo(args.output);

            #endregion

            #region Optional Icon
            // optional icon
            if (!string.IsNullOrEmpty(args.icon))
            {
                args.WriteLine(string.Format("Embedding icon \"{0}\"", args.icon));
                IconFile iconFile = new IconFile(args.icon);
                List<string> iconSizes = new List<string>();
                foreach (IconFileIcon icon in iconFile.Icons)
                    iconSizes.Add(icon.ToString());
                args.WriteLine(string.Format(" {0}", string.Join(", ", iconSizes.ToArray())));
                IconDirectoryResource iconDirectory = new IconDirectoryResource(iconFile);
                iconDirectory.Name = new ResourceId(128);
                iconDirectory.Language = ResourceUtil.NEUTRALLANGID;
                iconDirectory.SaveTo(args.output);
            }
            #endregion

            #region Manifest
            if (!string.IsNullOrEmpty(args.manifest))
            {
                args.WriteLine(string.Format("Embedding manifest \"{0}\"", args.manifest));
                ManifestResource manifest = new ManifestResource();
                manifest.Manifest.Load(args.manifest);
                manifest.SaveTo(args.output);
            }
            #endregion

            string supportdir = string.IsNullOrEmpty(args.apppath)
                ? Environment.CurrentDirectory
                : args.apppath;

            string templatepath = Path.GetDirectoryName(Path.GetFullPath(args.template));

            // create a temporary directory for CABs
            string cabtemp = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(cabtemp);
            args.WriteLine(string.Format("Writing CABs to \"{0}\"", cabtemp));

            try
            {
                #region Prepare CABs

                long totalSize = 0;
                List<String> allFilesList = new List<string>();

                // embedded files
                if (args.embed)
                {
                    args.WriteLine(string.Format("Compressing files in \"{0}\"", supportdir));
                    Dictionary<string, EmbedFileCollection> all_files = configfile.GetFiles(string.Empty, supportdir);
                    // ensure at least one for additional command-line parameters
                    if (all_files.Count == 0) all_files.Add(string.Empty, new EmbedFileCollection(supportdir));
                    Dictionary<string, EmbedFileCollection>.Enumerator enumerator = all_files.GetEnumerator();

                    while (enumerator.MoveNext())
                    {
                        EmbedFileCollection c_files = enumerator.Current.Value;

                        // add additional command-line files to the root CAB
                        if (string.IsNullOrEmpty(enumerator.Current.Key))
                        {
                            if (args.embedFiles != null)
                            {
                                foreach (string filename in args.embedFiles)
                                {
                                    string fullpath = Path.Combine(args.apppath, filename);
                                    c_files.Add(new EmbedFilePair(fullpath, filename));
                                }
                            }

                            if (args.embedFolders != null)
                            {
                                foreach (string folder in args.embedFolders)
                                {
                                    c_files.AddDirectory(folder);
                                }
                            }
                        }

                        if (c_files.Count == 0)
                            continue;

                        c_files.CheckFilesExist(args);
                        c_files.CheckFileAttributes(args);

                        ArrayList files = c_files.GetFilePairs();

                        // compress new CABs
                        string cabname = string.IsNullOrEmpty(enumerator.Current.Key)
                            ? Path.Combine(cabtemp, "SETUP_%d.CAB")
                            : Path.Combine(cabtemp, string.Format("SETUP_{0}_%d.CAB", enumerator.Current.Key));

                        Compress cab = new Compress();
                        long currentSize = 0;
                        cab.evFilePlaced += delegate(string s_File, int s32_FileSize, bool bContinuation)
                        {
                            if (!bContinuation)
                            {
                                totalSize += s32_FileSize;
                                currentSize += s32_FileSize;
                                args.WriteLine(String.Format(" {0} - {1}", s_File, EmbedFileCollection.FormatBytes(s32_FileSize)));
                            }

                            return 0;
                        };
                        cab.CompressFileList(files, cabname, true, true, args.embedResourceSize);

                        StringBuilder fileslist = new StringBuilder();
                        fileslist.AppendLine(string.Format("{0} CAB size: {1}",
                            string.IsNullOrEmpty(enumerator.Current.Key) ? "*" : enumerator.Current.Key,
                            EmbedFileCollection.FormatBytes(currentSize)));

                        fileslist.Append(" " + String.Join("\r\n ", c_files.GetFileValuesWithSize(2)));
                        allFilesList.Add(fileslist.ToString());
                    }
                }
                #endregion

                #region Resources
                // embed resources

                IntPtr h = ResourceUpdate.BeginUpdateResource(args.output, false);

                if (h == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                if (!string.IsNullOrEmpty(args.banner))
                {
                    args.WriteLine(string.Format("Embedding banner \"{0}\"", args.banner));
                    ResourceUpdate.WriteFile(h, new ResourceId("CUSTOM"), new ResourceId("RES_BANNER"),
                        ResourceUtil.NEUTRALLANGID, args.banner);
                }

                if (!string.IsNullOrEmpty(args.splash))
                {
                    args.WriteLine(string.Format("Embedding splash screen \"{0}\"", args.splash));
                    ResourceUpdate.WriteFile(h, new ResourceId("CUSTOM"), new ResourceId("RES_SPLASH"),
                        ResourceUtil.NEUTRALLANGID, args.splash);
                }

                args.WriteLine(string.Format("Embedding configuration \"{0}\"", configFilename));
                ResourceUpdate.WriteFile(h, new ResourceId("CUSTOM"), new ResourceId("RES_CONFIGURATION"),
                    ResourceUtil.NEUTRALLANGID, configFilename);

                #region Embed Resources

                EmbedFileCollection html_files = new EmbedFileCollection(args.apppath);

                if (args.htmlFiles != null)
                {
                    foreach (string filename in args.htmlFiles)
                    {
                        string fullpath = Path.GetFullPath(filename);
                        if (Directory.Exists(fullpath))
                        {
                            html_files.AddDirectory(fullpath);
                        }
                        else
                        {
                            html_files.Add(new EmbedFilePair(fullpath, Path.GetFileName(filename)));
                        }
                    }
                }

                IEnumerator<EmbedFilePair> html_files_enumerator = html_files.GetEnumerator();
                while (html_files_enumerator.MoveNext())
                {
                    EmbedFilePair pair = html_files_enumerator.Current;
                    String id = "";
                    for (int i = 0; i < pair.relativepath.Length; i++)
                    {
                        id += Char.IsLetterOrDigit(pair.relativepath[i]) ? pair.relativepath[i] : '_';
                    }

                    args.WriteLine(string.Format("Embedding HTML resource \"{0}\": {1}", id, pair.fullpath));
                    ResourceUpdate.WriteFile(h, new ResourceId("HTM"), new ResourceId(id.ToUpper()),
                        ResourceUtil.NEUTRALLANGID, pair.fullpath);
                }

                #endregion

                #region Embed CABs

                if (args.embed)
                {
                    args.WriteLine("Embedding CABs");
                    foreach (string cabfile in Directory.GetFiles(cabtemp))
                    {
                        args.WriteLine(string.Format(" {0} - {1}", Path.GetFileName(cabfile),
                            EmbedFileCollection.FormatBytes(new FileInfo(cabfile).Length)));

                        ResourceUpdate.WriteFile(h, new ResourceId("RES_CAB"), new ResourceId(Path.GetFileName(cabfile)),
                            ResourceUtil.NEUTRALLANGID, cabfile);
                    }

                    // cab directory

                    args.WriteLine("Embedding CAB directory");
                    StringBuilder filesDirectory = new StringBuilder();
                    filesDirectory.AppendLine(string.Format("Total CAB size: {0}\r\n", EmbedFileCollection.FormatBytes(totalSize)));
                    filesDirectory.AppendLine(string.Join("\r\n\r\n", allFilesList.ToArray()));
                    byte[] filesDirectory_b = Encoding.Unicode.GetBytes(filesDirectory.ToString());
                    ResourceUpdate.Write(h, new ResourceId("CUSTOM"), new ResourceId("RES_CAB_LIST"),
                        ResourceUtil.NEUTRALLANGID, filesDirectory_b);
                }

                #endregion

                // resource files
                ResourceFileCollection resources = configfile.GetResources(supportdir);
                foreach (ResourceFilePair r_pair in resources)
                {
                    args.WriteLine(string.Format("Embedding resource \"{0}\": {1}", r_pair.id, r_pair.path));
                    ResourceUpdate.WriteFile(h, new ResourceId("CUSTOM"), new ResourceId(r_pair.id),
                        ResourceUtil.NEUTRALLANGID, r_pair.path);
                }

                if (args.mslu)
                {
                    args.WriteLine("Embedding MSLU unicows.dll");

                    string unicowsdll = Path.Combine(templatepath, "unicows.dll");
                    if (! File.Exists(unicowsdll)) unicowsdll = Path.Combine(supportdir, "unicows.dll");
                    if (! File.Exists(unicowsdll)) unicowsdll = Path.Combine(Environment.CurrentDirectory, "unicows.dll");
                    if (! File.Exists(unicowsdll))
                    {
                        throw new Exception(string.Format("Error locating \"{0}\\unicows.dll\"", templatepath));
                    }

                    ResourceUpdate.WriteFile(h, new ResourceId("CUSTOM"), new ResourceId("RES_UNICOWS"),
                        ResourceUtil.NEUTRALLANGID, unicowsdll);
                }

                args.WriteLine(string.Format("Writing {0}", EmbedFileCollection.FormatBytes(totalSize)));

                if (!ResourceUpdate.EndUpdateResource(h, false))
                    throw new Win32Exception(Marshal.GetLastWin32Error());

                #endregion
            }
            finally
            {
                if (Directory.Exists(cabtemp))
                {
                    args.WriteLine(string.Format("Cleaning up \"{0}\"", cabtemp));
                    Directory.Delete(cabtemp, true);
                }

                if (!string.IsNullOrEmpty(configTemp))
                {
                    args.WriteLine(string.Format("Cleaning up \"{0}\"", configTemp));
                    File.Delete(configTemp);
                }
            }

            args.WriteLine(string.Format("Successfully created \"{0}\" ({1})",
                args.output, EmbedFileCollection.FormatBytes(new FileInfo(args.output).Length)));
        }
        public void TestExtractCab()
        {
            Console.WriteLine("TestExtractCab");

            // create a self-extracting bootstrapper
            ConfigFile configFile = new ConfigFile();
            SetupConfiguration setupConfiguration = new SetupConfiguration();
            configFile.Children.Add(setupConfiguration);
            InstallerLinkerArguments args = new InstallerLinkerArguments();
            args.config = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".xml");
            Console.WriteLine("Writing '{0}'", args.config);
            configFile.SaveAs(args.config);
            args.embed = true;
            args.apppath = Path.GetTempPath();
            args.embedFiles = new string[] { Path.GetFileName(args.config) };
            args.output = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".exe");
            args.template = dotNetInstallerExeUtils.Executable;
            Console.WriteLine("Linking '{0}'", args.output);
            InstallerLinkerExeUtils.CreateInstaller(args);
            Assert.IsTrue(File.Exists(args.output));
            // execute dotNetInstaller
            Assert.AreEqual(0, dotNetInstallerExeUtils.Run(args.output, "/ExtractCab"));
            // this should have created a directory called SupportFiles in the current directory
            string supportFilesPath = Path.Combine(Path.GetDirectoryName(args.output), "SupportFiles");
            Console.WriteLine("Checking {0}", supportFilesPath);
            Assert.IsTrue(Directory.Exists(supportFilesPath), string.Format("Missing {0}", supportFilesPath));
            File.Delete(args.config);
            File.Delete(args.output);
            Directory.Delete(supportFilesPath, true);
        }
        public void TestUserControlEditHtmlValues()
        {
            Console.WriteLine("TestUserControlEditHtmlValues");

            bool usingHtmlInstaller = dotNetInstallerExeUtils.Executable.EndsWith("htmlInstaller.exe");
            if (!usingHtmlInstaller) return;

            // a configuration with a checkbox control
            ConfigFile configFile = new ConfigFile();
            SetupConfiguration setupConfiguration = new SetupConfiguration();
            setupConfiguration.auto_start = true;
            setupConfiguration.failed_exec_command_continue = "";
            setupConfiguration.auto_close_on_error = true;
            configFile.Children.Add(setupConfiguration);
            ControlEdit edit = new ControlEdit();
            edit.Text = "3";
            edit.Id = "edit1";
            setupConfiguration.Children.Add(edit);
            ComponentCmd cmd = new ComponentCmd();
            cmd.command = "cmd.exe /C exit /b [edit1]1";
            cmd.required_install = true;
            setupConfiguration.Children.Add(cmd);
            // save config file
            InstallerLinkerArguments args = new InstallerLinkerArguments();
            args.config = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".xml");
            Console.WriteLine("Writing '{0}'", args.config);
            configFile.SaveAs(args.config);
            // create HTML directory
            string htmlPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(htmlPath);
            string htmlIndexFilename = Path.Combine(htmlPath, "index.html");
            File.WriteAllText(htmlIndexFilename,
                              @"<html><head><title></title></head><body>
                                <input type=""text"" id=""edit1"" value=""4"" />
                                <input id=""button_install"" type=""button"" value=""Install"" />
                                </body></html>");
            // link the install executable
            args.htmlFiles = new string[] { htmlPath };
            args.embed = true;
            args.apppath = Path.GetTempPath();
            args.embedFiles = new string[] { Path.GetFileName(args.config) };
            args.output = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".exe");
            args.template = dotNetInstallerExeUtils.Executable;
            Console.WriteLine("Linking '{0}'", args.output);
            InstallerLinkerExeUtils.CreateInstaller(args);
            Assert.IsTrue(File.Exists(args.output));
            // execute dotNetInstaller
            dotNetInstallerExeUtils.RunOptions runOptions = new dotNetInstallerExeUtils.RunOptions();
            runOptions.autostart = true;
            runOptions.quiet = false;
            Assert.AreEqual(41, dotNetInstallerExeUtils.Run(args.output, runOptions.CommandLineArgs));
            File.Delete(args.config);
            Directory.Delete(args.htmlFiles[0], true);
        }
        public void TestExtractCabTwoComponentsSameName()
        {
            Console.WriteLine("TestExtractCabTwoComponentsSameName");

            InstallerLinkerArguments args = new InstallerLinkerArguments();
            args.config = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".xml");
            Console.WriteLine("Writing '{0}'", args.config);
            args.embed = true;
            args.apppath = Path.GetTempPath();
            args.output = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".exe");
            args.template = dotNetInstallerExeUtils.Executable;
            // create a self-extracting bootstrapper
            ConfigFile configFile = new ConfigFile();
            SetupConfiguration setupConfiguration = new SetupConfiguration();
            configFile.Children.Add(setupConfiguration);

            for (int i = 0; i < 2; i++)
            {
                ComponentCmd component = new ComponentCmd();
                component.id = "component";
                setupConfiguration.Children.Add(component);
                EmbedFile embedfile = new EmbedFile();
                embedfile.sourcefilepath = args.config;
                embedfile.targetfilepath = string.Format("component{0}\\file.xml", i);
                component.Children.Add(embedfile);
            }

            configFile.SaveAs(args.config);
            Console.WriteLine("Linking '{0}'", args.output);
            InstallerLinkerExeUtils.CreateInstaller(args);
            Assert.IsTrue(File.Exists(args.output));
            // execute dotNetInstaller
            Assert.AreEqual(0, dotNetInstallerExeUtils.Run(args.output, "/ExtractCab"));
            // this should have created a directory called SupportFiles in the current directory
            string supportFilesPath = Path.Combine(Path.GetDirectoryName(args.output), "SupportFiles");
            Console.WriteLine("Checking {0}", supportFilesPath);
            Assert.IsTrue(Directory.Exists(supportFilesPath), string.Format("Missing {0}", supportFilesPath));
            Assert.IsTrue(Directory.Exists(supportFilesPath + @"\component0"));
            Assert.IsTrue(File.Exists(supportFilesPath + @"\component0\file.xml"));
            Assert.IsTrue(Directory.Exists(supportFilesPath + @"\component1"));
            Assert.IsTrue(File.Exists(supportFilesPath + @"\component1\file.xml"));
            File.Delete(args.config);
            File.Delete(args.output);
            Directory.Delete(supportFilesPath, true);
        }
        public static void CreateInstaller(InstallerLinkerArguments args)
        {
            args.Validate();

            args.WriteLine(string.Format("Creating \"{0}\" from \"{1}\"", args.output, args.template));
            System.IO.File.Copy(args.template, args.output, true);
            System.IO.File.SetAttributes(args.output, System.IO.FileAttributes.Normal);

            string configFilename = args.config;

            #region Version Information

            ConfigFile configfile = new ConfigFile();
            configfile.Load(configFilename);

            // \todo: check XML with XSD, warn if nodes are being dropped

            // filter the configuration
            string configTemp = null;
            if (!string.IsNullOrEmpty(args.processorArchitecture))
            {
                int configurationCount = configfile.ConfigurationCount;
                int componentCount     = configfile.ComponentCount;
                args.WriteLine(string.Format("Applying processor architecture filter \"{0}\"", args.processorArchitecture));
                ProcessorArchitectureFilter filter = new ProcessorArchitectureFilter(args.processorArchitecture);
                XmlDocument filteredXml            = configfile.GetXml(filter);
                configTemp = configFilename = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
                filteredXml.Save(configTemp);
                configfile.LoadXml(filteredXml);
                args.WriteLine(string.Format(" configurations: {0} => {1}", configurationCount, configfile.ConfigurationCount));
                args.WriteLine(string.Format(" components: {0} => {1}", componentCount, configfile.ComponentCount));
            }

            args.WriteLine(string.Format("Updating binary attributes in \"{0}\"", args.output));
            VersionResource rc = new VersionResource();
            rc.LoadFrom(args.output);

            // version information
            StringFileInfo stringFileInfo = (StringFileInfo)rc["StringFileInfo"];
            if (!string.IsNullOrEmpty(configfile.productversion))
            {
                rc.ProductVersion = configfile.productversion;
                stringFileInfo["ProductVersion"] = configfile.productversion;
            }

            if (!string.IsNullOrEmpty(configfile.fileversion))
            {
                rc.FileVersion = configfile.fileversion;
                stringFileInfo["FileVersion"] = configfile.fileversion;
            }

            foreach (FileAttribute attr in configfile.fileattributes)
            {
                args.WriteLine(string.Format(" {0}: {1}", attr.name, attr.value));
                stringFileInfo[attr.name] = attr.value;
            }

            rc.Language = ResourceUtil.NEUTRALLANGID;
            rc.SaveTo(args.output);

            #endregion

            #region Optional Icon
            // optional icon
            if (!string.IsNullOrEmpty(args.icon))
            {
                args.WriteLine(string.Format("Embedding icon \"{0}\"", args.icon));
                IconFile      iconFile  = new IconFile(args.icon);
                List <string> iconSizes = new List <string>();
                foreach (IconFileIcon icon in iconFile.Icons)
                {
                    iconSizes.Add(icon.ToString());
                }
                args.WriteLine(string.Format(" {0}", string.Join(", ", iconSizes.ToArray())));
                IconDirectoryResource iconDirectory = new IconDirectoryResource(iconFile);
                iconDirectory.Name     = new ResourceId(128);
                iconDirectory.Language = ResourceUtil.NEUTRALLANGID;
                iconDirectory.SaveTo(args.output);
            }
            #endregion

            #region Manifest
            if (!string.IsNullOrEmpty(args.manifest))
            {
                args.WriteLine(string.Format("Embedding manifest \"{0}\"", args.manifest));
                ManifestResource manifest = new ManifestResource();
                manifest.Manifest.Load(args.manifest);
                manifest.SaveTo(args.output);
            }
            #endregion

            string supportdir = string.IsNullOrEmpty(args.apppath)
                ? Environment.CurrentDirectory
                : args.apppath;

            string templatepath = Path.GetDirectoryName(Path.GetFullPath(args.template));

            // create a temporary directory for CABs
            string cabtemp = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(cabtemp);
            args.WriteLine(string.Format("Writing CABs to \"{0}\"", cabtemp));

            try
            {
                #region Prepare CABs

                long          totalSize    = 0;
                List <String> allFilesList = new List <string>();

                // embedded files
                if (args.embed)
                {
                    args.WriteLine(string.Format("Compressing files in \"{0}\"", supportdir));
                    Dictionary <string, EmbedFileCollection> all_files = configfile.GetFiles(string.Empty, supportdir);
                    // ensure at least one for additional command-line parameters
                    if (all_files.Count == 0)
                    {
                        all_files.Add(string.Empty, new EmbedFileCollection(supportdir));
                    }
                    using (Dictionary <string, EmbedFileCollection> .Enumerator enumerator = all_files.GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            EmbedFileCollection c_files = enumerator.Current.Value;

                            // add additional command-line files to the root CAB
                            if (string.IsNullOrEmpty(enumerator.Current.Key))
                            {
                                if (args.embedFiles != null)
                                {
                                    foreach (string filename in args.embedFiles)
                                    {
                                        string fullpath = Path.Combine(args.apppath, filename);
                                        c_files.Add(new EmbedFilePair(fullpath, filename));
                                    }
                                }

                                if (args.embedFolders != null)
                                {
                                    foreach (string folder in args.embedFolders)
                                    {
                                        c_files.AddDirectory(folder);
                                    }
                                }
                            }

                            if (c_files.Count == 0)
                            {
                                continue;
                            }

                            c_files.CheckFilesExist(args);
                            c_files.CheckFileAttributes(args);

                            ArrayList files = c_files.GetFilePairs();

                            // compress new CABs
                            string cabname = string.IsNullOrEmpty(enumerator.Current.Key)
                                ? Path.Combine(cabtemp, "SETUP_%d.CAB")
                                : Path.Combine(cabtemp, string.Format("SETUP_{0}_%d.CAB", enumerator.Current.Key));

                            Compress cab         = new Compress();
                            long     currentSize = 0;
                            cab.evFilePlaced += delegate(string s_File, int s32_FileSize, bool bContinuation)
                            {
                                if (!bContinuation)
                                {
                                    totalSize   += s32_FileSize;
                                    currentSize += s32_FileSize;
                                    args.WriteLine(String.Format(" {0} - {1}", s_File, EmbedFileCollection.FormatBytes(s32_FileSize)));
                                }

                                return(0);
                            };
                            cab.CompressFileList(files, cabname, true, true, args.embedResourceSize);

                            StringBuilder fileslist = new StringBuilder();
                            fileslist.AppendLine(string.Format("{0} CAB size: {1}",
                                                               string.IsNullOrEmpty(enumerator.Current.Key) ? "*" : enumerator.Current.Key,
                                                               EmbedFileCollection.FormatBytes(currentSize)));

                            fileslist.Append(" " + String.Join("\r\n ", c_files.GetFileValuesWithSize(2)));
                            allFilesList.Add(fileslist.ToString());
                        }
                    }
                }
                #endregion

                #region Resources
                // embed resources

                IntPtr h = ResourceUpdate.BeginUpdateResource(args.output, false);

                if (h == IntPtr.Zero)
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                if (!string.IsNullOrEmpty(args.banner))
                {
                    args.WriteLine(string.Format("Embedding banner \"{0}\"", args.banner));
                    ResourceUpdate.WriteFile(h, new ResourceId("CUSTOM"), new ResourceId("RES_BANNER"),
                                             ResourceUtil.NEUTRALLANGID, args.banner);
                }

                if (!string.IsNullOrEmpty(args.splash))
                {
                    args.WriteLine(string.Format("Embedding splash screen \"{0}\"", args.splash));
                    ResourceUpdate.WriteFile(h, new ResourceId("CUSTOM"), new ResourceId("RES_SPLASH"),
                                             ResourceUtil.NEUTRALLANGID, args.splash);
                }

                args.WriteLine(string.Format("Embedding configuration \"{0}\"", configFilename));
                ResourceUpdate.WriteFile(h, new ResourceId("CUSTOM"), new ResourceId("RES_CONFIGURATION"),
                                         ResourceUtil.NEUTRALLANGID, configFilename);

                #region Embed Resources

                EmbedFileCollection html_files = new EmbedFileCollection(args.apppath);

                if (args.htmlFiles != null)
                {
                    foreach (string filename in args.htmlFiles)
                    {
                        string fullpath = Path.GetFullPath(filename);
                        if (Directory.Exists(fullpath))
                        {
                            html_files.AddDirectory(fullpath);
                        }
                        else
                        {
                            html_files.Add(new EmbedFilePair(fullpath, Path.GetFileName(filename)));
                        }
                    }
                }

                using (IEnumerator <EmbedFilePair> html_files_enumerator = html_files.GetEnumerator())
                {
                    while (html_files_enumerator.MoveNext())
                    {
                        EmbedFilePair pair = html_files_enumerator.Current;
                        String        id   = "";
                        for (int i = 0; i < pair.relativepath.Length; i++)
                        {
                            id += Char.IsLetterOrDigit(pair.relativepath[i]) ? pair.relativepath[i] : '_';
                        }

                        args.WriteLine(string.Format("Embedding HTML resource \"{0}\": {1}", id, pair.fullpath));
                        ResourceUpdate.WriteFile(h, new ResourceId("HTM"), new ResourceId(id.ToUpper()),
                                                 ResourceUtil.NEUTRALLANGID, pair.fullpath);
                    }
                }

                #endregion

                #region Embed CABs

                if (args.embed)
                {
                    args.WriteLine("Embedding CABs");
                    foreach (string cabfile in Directory.GetFiles(cabtemp))
                    {
                        args.WriteLine(string.Format(" {0} - {1}", Path.GetFileName(cabfile),
                                                     EmbedFileCollection.FormatBytes(new FileInfo(cabfile).Length)));

                        ResourceUpdate.WriteFile(h, new ResourceId("RES_CAB"), new ResourceId(Path.GetFileName(cabfile)),
                                                 ResourceUtil.NEUTRALLANGID, cabfile);
                    }

                    // cab directory

                    args.WriteLine("Embedding CAB directory");
                    StringBuilder filesDirectory = new StringBuilder();
                    filesDirectory.AppendLine(string.Format("Total CAB size: {0}\r\n", EmbedFileCollection.FormatBytes(totalSize)));
                    filesDirectory.AppendLine(string.Join("\r\n\r\n", allFilesList.ToArray()));
                    byte[] filesDirectory_b = Encoding.Unicode.GetBytes(filesDirectory.ToString());
                    ResourceUpdate.Write(h, new ResourceId("CUSTOM"), new ResourceId("RES_CAB_LIST"),
                                         ResourceUtil.NEUTRALLANGID, filesDirectory_b);
                }

                #endregion

                // resource files
                ResourceFileCollection resources = configfile.GetResources(supportdir);
                foreach (ResourceFilePair r_pair in resources)
                {
                    args.WriteLine(string.Format("Embedding resource \"{0}\": {1}", r_pair.id, r_pair.path));
                    ResourceUpdate.WriteFile(h, new ResourceId("CUSTOM"), new ResourceId(r_pair.id),
                                             ResourceUtil.NEUTRALLANGID, r_pair.path);
                }

                args.WriteLine(string.Format("Writing {0}", EmbedFileCollection.FormatBytes(totalSize)));

                if (!ResourceUpdate.EndUpdateResource(h, false))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                #endregion
            }
            finally
            {
                if (Directory.Exists(cabtemp))
                {
                    args.WriteLine(string.Format("Cleaning up \"{0}\"", cabtemp));
                    Directory.Delete(cabtemp, true);
                }

                if (!string.IsNullOrEmpty(configTemp))
                {
                    args.WriteLine(string.Format("Cleaning up \"{0}\"", configTemp));
                    File.Delete(configTemp);
                }
            }

            args.WriteLine(string.Format("Successfully created \"{0}\" ({1})",
                                         args.output, EmbedFileCollection.FormatBytes(new FileInfo(args.output).Length)));
        }
 public void TestLinkDefaultManifest()
 {
     InstallerLinkerArguments args = new InstallerLinkerArguments();
     try
     {
         ConfigFile configFile = new ConfigFile();
         SetupConfiguration setupConfiguration = new SetupConfiguration();
         configFile.Children.Add(setupConfiguration);
         args.config = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".xml");
         Console.WriteLine("Writing '{0}'", args.config);
         configFile.SaveAs(args.config);
         args.output = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".exe");
         Console.WriteLine("Linking '{0}'", args.output);
         args.template = dotNetInstallerExeUtils.Executable;
         InstallerLib.InstallerLinker.CreateInstaller(args);
         // check that the linker generated output
         Assert.IsTrue(File.Exists(args.output));
         Assert.IsTrue(new FileInfo(args.output).Length > 0);
         using (ResourceInfo ri = new ResourceInfo())
         {
             ri.Load(args.output);
             List<Resource> manifests = ri.Resources[new ResourceId(Kernel32.ResourceTypes.RT_MANIFEST)]; // RT_MANIFEST
             Assert.IsNotNull(manifests);
             Assert.AreEqual(1, manifests.Count);
             ManifestResource manifest = (ManifestResource)manifests[0]; // RT_MANIFEST
             Console.WriteLine(manifest.Manifest.OuterXml);
             XmlNamespaceManager manifestNamespaceManager = new XmlNamespaceManager(manifest.Manifest.NameTable);
             manifestNamespaceManager.AddNamespace("v1", "urn:schemas-microsoft-com:asm.v1");
             manifestNamespaceManager.AddNamespace("v3", "urn:schemas-microsoft-com:asm.v3");
             string level = manifest.Manifest.SelectSingleNode("//v3:requestedExecutionLevel",
                 manifestNamespaceManager).Attributes["level"].Value;
             Assert.AreEqual(level, "requireAdministrator");
         }
     }
     finally
     {
         if (File.Exists(args.config))
             File.Delete(args.config);
         if (File.Exists(args.output))
             File.Delete(args.output);
     }
 }