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); }
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); } }
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); } }