internal static string CreateSelfExtractor(string pcName, string tempInstallersPathTemp) { string convertedPCName = pcName.Replace(" ", "_").Replace("\\", "_").Replace("/", "_"); using (ZipFile zf = new ZipFile()) { zf.AddDirectory(tempInstallersPathTemp); SelfExtractorSaveOptions options = new SelfExtractorSaveOptions(); options.Copyright = "Oxigen"; options.DefaultExtractDirectory = "%TEMP%\\Oxigen"; options.Flavor = SelfExtractorFlavor.ConsoleApplication; options.ProductName = "Oxigen"; options.Quiet = true; options.RemoveUnpackedFilesAfterExecute = true; options.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently; options.PostExtractCommandLine = "%TEMP%\\Oxigen\\Setup.exe"; zf.SaveSelfExtractor(tempInstallersPathTemp + "\\" + convertedPCName + ".exe", options); } // sign the self-extractor RunProcessAndWaitForExit(System.Configuration.ConfigurationSettings.AppSettings["signToolPath"], System.Configuration.ConfigurationSettings.AppSettings["signToolArguments"] + "\"" + tempInstallersPathTemp + convertedPCName + ".exe\" >> " + System.Configuration.ConfigurationSettings.AppSettings["debugPath"]); return(convertedPCName); }
private int Convert() { Console.Out.WriteLine("Converting file {0} to SFX {1}", ZipFileToConvert, targetName); var options = new ReadOptions { StatusMessageWriter = Console.Out }; using (ZipFile zip = ZipFile.Read(ZipFileToConvert, options)) { zip.Comment = ZipComment; zip.UseZip64WhenSaving = Zip64Option.AsNecessary; SelfExtractorSaveOptions sfxOptions = new SelfExtractorSaveOptions(); sfxOptions.Flavor = flavor; sfxOptions.DefaultExtractDirectory = ExtractDir; sfxOptions.PostExtractCommandLine = ExeOnUnpack; sfxOptions.SfxExeWindowTitle = Title; sfxOptions.Description = Description; sfxOptions.FileVersion = FileVersion; sfxOptions.IconFile = IconFile; // ExtractExistingFile : always default value throw sfxOptions.ProductName = Name; sfxOptions.ProductVersion = Version; sfxOptions.Copyright = Copyright; sfxOptions.AdditionalCompilerSwitches = Compiler; sfxOptions.Quiet = false; sfxOptions.RemoveUnpackedFilesAfterExecute = false; zip.SaveSelfExtractor(targetName, sfxOptions); } return(0); }
public void Do() { var pathToCompress = @"C:\dev\posh-git"; using (var zip = new ZipFile()) { zip.AddDirectory(pathToCompress, "pathToStoreAsInZip"); zip.Comment = "This is shown in the win from, in the comment area"; var opts = new SelfExtractorSaveOptions(); opts.Flavor = SelfExtractorFlavor.WinFormsApplication; //winform or console modes opts.DefaultExtractDirectory = @"C:\dev\bob"; opts.PostExtractCommandLine = "install.exe"; opts.RemoveUnpackedFilesAfterExecute = false; opts.ProductName = "Dovetail"; opts.Copyright = "© Dovetail Software"; opts.Description = "My Desc"; opts.FileVersion = new Version(1, 0, 0, 0); opts.IconFile = "dt icon???"; opts.ProductVersion = "1.2.0.0"; zip.SaveSelfExtractor("dovetail.exe", opts); } }
static void Main(string[] args) { var convertedPCName = args[0]; var tempInstallersPathTemp = args[1]; using (ZipFile zf = new ZipFile()) { zf.AddDirectory(tempInstallersPathTemp); SelfExtractorSaveOptions options = new SelfExtractorSaveOptions(); options.Copyright = "Oxigen"; options.DefaultExtractDirectory = "%TEMP%\\Oxigen"; options.Flavor = SelfExtractorFlavor.ConsoleApplication; options.ProductName = "Oxigen"; options.Quiet = true; options.RemoveUnpackedFilesAfterExecute = true; options.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently; options.PostExtractCommandLine = "%TEMP%\\Oxigen\\Setup.exe"; zf.SaveSelfExtractor(tempInstallersPathTemp + "\\" + convertedPCName + ".exe", options); } }
private void Convert() { string TargetName = ZipFileToConvert.Replace(".zip", ".exe"); Console.WriteLine("Converting file {0} to SFX {1}", ZipFileToConvert, TargetName); var options = new ReadOptions { StatusMessageWriter = System.Console.Out }; using (ZipFile zip = ZipFile.Read(ZipFileToConvert, options)) { zip.Comment = ZipComment; SelfExtractorSaveOptions sfxOptions = new SelfExtractorSaveOptions(); sfxOptions.Flavor = flavor; sfxOptions.DefaultExtractDirectory = ExtractDir; sfxOptions.PostExtractCommandLine = ExeOnUnpack; zip.SaveSelfExtractor(TargetName, sfxOptions); } }
private static void PackageEN5Player() { // find EN5Player.exe and dependencies var filesToPackage = new List <string>(); var baseDirectory = AppDomain.CurrentDomain.BaseDirectory; var thisName = $"{Assembly.GetExecutingAssembly().GetName().Name}.exe"; foreach (var file in Directory.EnumerateFiles(baseDirectory)) { if (file.EndsWith($"{thisName}")) { continue; } if (file.EndsWith(".exe") || file.EndsWith(".dll") || file.EndsWith(".ico")) { filesToPackage.Add(file); } } // package them together into a single executable file using (var zip = new ZipFile()) { zip.Password = "******"; foreach (var file in filesToPackage) { zip.AddFile(file, ""); } var options = new SelfExtractorSaveOptions { Flavor = SelfExtractorFlavor.ConsoleApplication, Quiet = true }; // exe file info var appInfo = new AppInfo(typeof(AppInfo).Assembly); var launcherName = $"{appInfo.Name}.exe"; options.IconFile = $"{baseDirectory}\\icon.ico"; options.ProductName = appInfo.Name; options.Description = appInfo.Description; options.Copyright = appInfo.Copyright; options.ProductVersion = appInfo.Version; options.FileVersion = Version.Parse(appInfo.Version); // extract options.DefaultExtractDirectory = $"%APPDATA%\\{appInfo.Name}"; options.PostExtractCommandLine = $"%APPDATA%\\{appInfo.Name}\\{launcherName}"; options.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently; // zip var package = $"{baseDirectory}\\Package"; if (!Directory.Exists(package)) { Directory.CreateDirectory(package); } zip.SaveSelfExtractor($"{package}\\{launcherName}", options); } }
public void SelfExtractor_WinForms() { string[] Passwords = { null, "12345" }; for (int k = 0; k < Passwords.Length; k++) { string exeFileToCreate = Path.Combine(TopLevelDir, String.Format("SelfExtractor_WinForms-{0}.exe", k)); string DesiredUnpackDirectory = Path.Combine(TopLevelDir, String.Format("unpack{0}", k)); String filename = null; string Subdir = Path.Combine(TopLevelDir, String.Format("A{0}", k)); Directory.CreateDirectory(Subdir); var checksums = new Dictionary <string, string>(); int fileCount = _rnd.Next(10) + 10; for (int j = 0; j < fileCount; j++) { filename = Path.Combine(Subdir, String.Format("file{0:D3}.txt", j)); TestUtilities.CreateAndFillFileText(filename, _rnd.Next(34000) + 5000); var chk = TestUtilities.ComputeChecksum(filename); checksums.Add(filename, TestUtilities.CheckSumToString(chk)); } using (ZipFile zip = new ZipFile()) { zip.Password = Passwords[k]; zip.AddDirectory(Subdir, Path.GetFileName(Subdir)); zip.Comment = "For testing purposes, please extract to: " + DesiredUnpackDirectory; if (Passwords[k] != null) { zip.Comment += String.Format("\r\n\r\nThe password for all entries is: {0}\n", Passwords[k]); } SelfExtractorSaveOptions sfxOptions = new SelfExtractorSaveOptions(); sfxOptions.Flavor = Ionic.Zip.SelfExtractorFlavor.WinFormsApplication; sfxOptions.DefaultExtractDirectory = DesiredUnpackDirectory; zip.SaveSelfExtractor(exeFileToCreate, sfxOptions); } // run the self-extracting EXE we just created System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(exeFileToCreate); psi.Arguments = DesiredUnpackDirectory; psi.WorkingDirectory = TopLevelDir; psi.UseShellExecute = false; psi.CreateNoWindow = true; System.Diagnostics.Process process = System.Diagnostics.Process.Start(psi); process.WaitForExit(); // now, compare the output in TargetDirectory with the original string DirToCheck = Path.Combine(DesiredUnpackDirectory, String.Format("A{0}", k)); // verify the checksum of each file matches with its brother var fileList = Directory.GetFiles(DirToCheck); Assert.AreEqual <Int32>(checksums.Keys.Count, fileList.Length, "Trial {0}: Inconsistent results.", k); foreach (string fname in fileList) { string expectedCheckString = checksums[fname.Replace(String.Format("\\unpack{0}", k), "")]; string actualCheckString = TestUtilities.CheckSumToString(TestUtilities.ComputeChecksum(fname)); Assert.AreEqual <String>(expectedCheckString, actualCheckString, "Trial {0}: Unexpected checksum on extracted filesystem file ({1}).", k, fname); } } }
public void _Internal_SelfExtractor_Command(string cmdFormat, SelfExtractorFlavor flavor, bool runPostExtract, bool quiet, bool forceNoninteractive, bool wantArgs) { TestContext.WriteLine("=============================="); TestContext.WriteLine("SelfExtractor_RunOnExit({0})", flavor.ToString()); int entriesAdded = 0; String filename = null; string postExtractExe = String.Format(cmdFormat, _rnd.Next(3000)); // If WinForms and want forceNoninteractive, have the post-extract-exe return 0, // else, select a random number. int expectedReturnCode = (forceNoninteractive && flavor == SelfExtractorFlavor.WinFormsApplication) ? 0 : _rnd.Next(1024) + 20; TestContext.WriteLine("The post-extract command ({0}) will return {1}", postExtractExe, expectedReturnCode); string Subdir = Path.Combine(TopLevelDir, "A"); Directory.CreateDirectory(Subdir); var checksums = new Dictionary <string, string>(); int fileCount = _rnd.Next(10) + 10; for (int j = 0; j < fileCount; j++) { filename = Path.Combine(Subdir, String.Format("file{0:D3}.txt", j)); TestUtilities.CreateAndFillFileText(filename, _rnd.Next(34000) + 5000); entriesAdded++; var chk = TestUtilities.ComputeChecksum(filename); checksums.Add(filename, TestUtilities.CheckSumToString(chk)); TestContext.WriteLine("checksum({0})= ({1})", filename, checksums[filename]); } Directory.SetCurrentDirectory(TopLevelDir); for (int k = 0; k < 2; k++) { string ReadmeString = String.Format("Hey there! This zipfile entry was created directly " + "from a string in application code. Flavor ({0}) Trial({1})", flavor.ToString(), k); string exeFileToCreate = Path.Combine(TopLevelDir, String.Format("SelfExtractor_Command.{0}.{1}.exe", flavor.ToString(), k)); TestContext.WriteLine("----------------------"); TestContext.WriteLine("Trial {0}", k); string UnpackDirectory = String.Format("unpack.{0}", k); if (k != 0) { CompileApp(expectedReturnCode, postExtractExe); } var sw = new System.IO.StringWriter(); using (ZipFile zip = new ZipFile()) { zip.StatusMessageTextWriter = sw; zip.AddDirectory(Subdir, Path.GetFileName(Subdir)); zip.Comment = String.Format("Trial options: flavor({0}) command: ({3})\r\n" + "actuallyRun({1})\r\nquiet({2})\r\n" + "exists? {4}\r\nexpected rc={5}", flavor, runPostExtract, quiet, postExtractExe, k != 0, expectedReturnCode ); MemoryStream ms1 = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(ReadmeString)); zip.AddEntry("Readme.txt", ms1); if (k != 0) { zip.AddFile(postExtractExe); } SelfExtractorSaveOptions sfxOptions = new SelfExtractorSaveOptions(); sfxOptions.Flavor = flavor; sfxOptions.DefaultExtractDirectory = UnpackDirectory; sfxOptions.Quiet = quiet; // In the case of k==0, this exe does not exist. It will result in // a return code of 5. In k == 1, the exe exists and will succeed. if (postExtractExe.Contains(' ')) { sfxOptions.PostExtractCommandLine = "\"" + postExtractExe + "\""; } else { sfxOptions.PostExtractCommandLine = postExtractExe; } if (wantArgs) { sfxOptions.PostExtractCommandLine += " arg1 arg2"; } zip.SaveSelfExtractor(exeFileToCreate, sfxOptions); } TestContext.WriteLine("status output: " + sw.ToString()); if (k != 0) { File.Delete(postExtractExe); } // Run the post-extract-exe, conditionally. // We always run, unless specifically asked not to, OR // if it's a winforms app and we want it to be noninteractive and there's no EXE to run. // If we try running a non-existent app, it will pop an error message, hence user interaction, // which we need to avoid for the automated test. if (runPostExtract && (k != 0 || !forceNoninteractive || flavor != SelfExtractorFlavor.WinFormsApplication)) { TestContext.WriteLine("Running the SFX... "); System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(exeFileToCreate); psi.WorkingDirectory = TopLevelDir; psi.UseShellExecute = false; psi.CreateNoWindow = true; // false; System.Diagnostics.Process process = System.Diagnostics.Process.Start(psi); process.WaitForExit(); int rc = process.ExitCode; TestContext.WriteLine("SFX exit code: ({0})", rc); // The exit code is returned only if it's a console SFX. if (flavor == SelfExtractorFlavor.ConsoleApplication) { // The program actually runs if k != 0 if (k != 0) { // The file to execute should have returned a specific code. Assert.AreEqual <Int32>(expectedReturnCode, rc, "In trial {0}, the exit code did not match.", k); } else { // The file to execute should not have been found, hence rc==5. Assert.AreEqual <Int32>(5, rc, "In trial {0}, the exit code was unexpected.", k); } } else { Assert.AreEqual <Int32>(0, rc, "In trial {0}, the exit code did not match.", k); } // now, compare the output in UnpackDirectory with the original string DirToCheck = Path.Combine(TopLevelDir, Path.Combine(UnpackDirectory, "A")); // verify the checksum of each file matches with its brother foreach (string fname in Directory.GetFiles(DirToCheck)) { string originalName = fname.Replace("\\" + UnpackDirectory, ""); if (checksums.ContainsKey(originalName)) { string expectedCheckString = checksums[originalName]; string actualCheckString = TestUtilities.CheckSumToString(TestUtilities.ComputeChecksum(fname)); Assert.AreEqual <String>(expectedCheckString, actualCheckString, "Unexpected checksum on extracted filesystem file ({0}).", fname); } else { Assert.AreEqual <string>("Readme.txt", originalName); } } } } }
public void SelfExtractor_Console() { string exeFileToCreate = Path.Combine(TopLevelDir, "SelfExtractor_Console.exe"); string UnpackDirectory = Path.Combine(TopLevelDir, "unpack"); string ReadmeString = "Hey there! This zipfile entry was created directly from a string in application code."; int entriesAdded = 0; String filename = null; string Subdir = Path.Combine(TopLevelDir, "A"); Directory.CreateDirectory(Subdir); var checksums = new Dictionary <string, string>(); int fileCount = _rnd.Next(10) + 10; for (int j = 0; j < fileCount; j++) { filename = Path.Combine(Subdir, String.Format("file{0:D3}.txt", j)); TestUtilities.CreateAndFillFileText(filename, _rnd.Next(34000) + 5000); entriesAdded++; var chk = TestUtilities.ComputeChecksum(filename); checksums.Add(filename, TestUtilities.CheckSumToString(chk)); } using (ZipFile zip = new ZipFile()) { zip.AddDirectory(Subdir, Path.GetFileName(Subdir)); zip.Comment = "This will be embedded into a self-extracting exe"; MemoryStream ms1 = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(ReadmeString)); zip.AddEntry("Readme.txt", ms1); SelfExtractorSaveOptions sfxOptions = new SelfExtractorSaveOptions(); sfxOptions.Flavor = Ionic.Zip.SelfExtractorFlavor.ConsoleApplication; sfxOptions.DefaultExtractDirectory = UnpackDirectory; zip.SaveSelfExtractor(exeFileToCreate, sfxOptions); } var psi = new System.Diagnostics.ProcessStartInfo(exeFileToCreate); psi.WorkingDirectory = TopLevelDir; psi.UseShellExecute = false; psi.CreateNoWindow = true; System.Diagnostics.Process process = System.Diagnostics.Process.Start(psi); process.WaitForExit(); // now, compare the output in UnpackDirectory with the original string DirToCheck = Path.Combine(UnpackDirectory, "A"); // verify the checksum of each file matches with its brother foreach (string fname in Directory.GetFiles(DirToCheck)) { string originalName = fname.Replace("\\unpack", ""); if (checksums.ContainsKey(originalName)) { string expectedCheckString = checksums[originalName]; string actualCheckString = TestUtilities.CheckSumToString(TestUtilities.ComputeChecksum(fname)); Assert.AreEqual <String>(expectedCheckString, actualCheckString, "Unexpected checksum on extracted filesystem file ({0}).", fname); } else { Assert.AreEqual <string>("Readme.txt", originalName); } } }
private void SelfExtractor_Update(SelfExtractorFlavor flavor) { string SfxFileToCreate = Path.Combine(TopLevelDir, String.Format("SelfExtractor_Update{0}.exe", flavor.ToString())); string UnpackDirectory = Path.Combine(TopLevelDir, "unpack"); if (Directory.Exists(UnpackDirectory)) { Directory.Delete(UnpackDirectory, true); } string ReadmeString = "Hey there! This zipfile entry was created directly from a string in application code."; // create a file and compute the checksum string Subdir = Path.Combine(TopLevelDir, "files"); Directory.CreateDirectory(Subdir); var checksums = new Dictionary <string, string>(); string filename = Path.Combine(Subdir, "file1.txt"); TestUtilities.CreateAndFillFileText(filename, _rnd.Next(34000) + 5000); var chk = TestUtilities.ComputeChecksum(filename); checksums.Add(filename.Replace(TopLevelDir + "\\", "").Replace('\\', '/'), TestUtilities.CheckSumToString(chk)); // create the SFX using (ZipFile zip1 = new ZipFile()) { zip1.AddFile(filename, Path.GetFileName(Subdir)); zip1.Comment = "This will be embedded into a self-extracting exe"; MemoryStream ms1 = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(ReadmeString)); zip1.AddEntry("Readme.txt", ms1); SelfExtractorSaveOptions sfxOptions = new SelfExtractorSaveOptions(); sfxOptions.Flavor = flavor; sfxOptions.Quiet = true; sfxOptions.DefaultExtractDirectory = UnpackDirectory; zip1.SaveSelfExtractor(SfxFileToCreate, sfxOptions); } // verify count Assert.AreEqual <int>(TestUtilities.CountEntries(SfxFileToCreate), 2, "The Zip file has the wrong number of entries."); // create another file filename = Path.Combine(Subdir, "file2.txt"); TestUtilities.CreateAndFillFileText(filename, _rnd.Next(34000) + 5000); chk = TestUtilities.ComputeChecksum(filename); checksums.Add(filename.Replace(TopLevelDir + "\\", "").Replace('\\', '/'), TestUtilities.CheckSumToString(chk)); string password = "******"; // update the SFX using (ZipFile zip1 = ZipFile.Read(SfxFileToCreate)) { zip1.CompressionLevel = Ionic.Zlib.CompressionLevel.BestCompression; zip1.Encryption = EncryptionAlgorithm.WinZipAes256; zip1.Comment = "The password is: " + password; zip1.Password = password; zip1.AddFile(filename, Path.GetFileName(Subdir)); SelfExtractorSaveOptions sfxOptions = new SelfExtractorSaveOptions(); sfxOptions.Flavor = flavor; sfxOptions.Quiet = true; sfxOptions.DefaultExtractDirectory = UnpackDirectory; zip1.SaveSelfExtractor(SfxFileToCreate, sfxOptions); } // verify count Assert.AreEqual <int>(TestUtilities.CountEntries(SfxFileToCreate), 3, "The Zip file has the wrong number of entries."); // read the SFX TestContext.WriteLine("---------------Reading {0}...", SfxFileToCreate); using (ZipFile zip2 = ZipFile.Read(SfxFileToCreate)) { zip2.Password = password; //string extractDir = String.Format("extract{0}", j); foreach (var e in zip2) { TestContext.WriteLine(" Entry: {0} c({1}) u({2})", e.FileName, e.CompressedSize, e.UncompressedSize); e.Extract(UnpackDirectory); if (!e.IsDirectory) { if (checksums.ContainsKey(e.FileName)) { filename = Path.Combine(UnpackDirectory, e.FileName); string actualCheckString = TestUtilities.CheckSumToString(TestUtilities.ComputeChecksum(filename)); Assert.AreEqual <string>(checksums[e.FileName], actualCheckString, "Checksums for ({1}) do not match.", e.FileName); //TestContext.WriteLine(" Checksums match ({0}).\n", actualCheckString); } else { Assert.AreEqual <string>("Readme.txt", e.FileName); } } } } int N = (flavor == SelfExtractorFlavor.ConsoleApplication) ? 2 : 1; for (int j = 0; j < N; j++) { // run the SFX TestContext.WriteLine("Running the SFX... "); var psi = new System.Diagnostics.ProcessStartInfo(SfxFileToCreate); if (flavor == SelfExtractorFlavor.ConsoleApplication) { if (j == 0) { psi.Arguments = "-o -p " + password; // overwrite } else { psi.Arguments = "-p " + password; } } psi.WorkingDirectory = TopLevelDir; psi.UseShellExecute = false; psi.CreateNoWindow = true; System.Diagnostics.Process process = System.Diagnostics.Process.Start(psi); process.WaitForExit(); int rc = process.ExitCode; TestContext.WriteLine("SFX exit code: ({0})", rc); if (j == 0) { Assert.AreEqual <Int32>(0, rc, "The exit code from the SFX was nonzero ({0}).", rc); } else { Assert.AreNotEqual <Int32>(0, rc, "The exit code from the SFX was zero ({0})."); } } // verify the unpacked files? }
/// <summary> /// Wrap the specified *.enbx file together with the working directory of EasiNote5 into a single executable file. /// </summary> /// <param name="enbxFileName">The specified *.enbx file that to be wrapped.</param> /// <param name="outputFileName">The file name of the single executable file.</param> public static void WrapToExe(string enbxFileName, string outputFileName) { // 1. verify parameters if (!File.Exists(enbxFileName)) { throw new FileNotFoundException(enbxFileName); } if (Path.GetExtension(enbxFileName) != Configuration.EN5FileExtension) { throw new FormatException($"*.{Configuration.EN5FileExtension} was expected."); } if (Path.GetExtension(outputFileName) != Configuration.ExeFileExtension) { outputFileName += Configuration.ExeFileExtension; } // 2. get the information about EasiNote5 var version = EN5Locator.GetVersion(); var directory = EN5Locator.GetWorkingDirectory(); if (string.IsNullOrEmpty(directory) || !Directory.Exists(directory) || string.IsNullOrEmpty(version)) { throw new NotInstalledException(Configuration.EN5AppName); } // launcher var extractDirectory = $"%APPDATA%\\{AppInfo.Current.Name}"; var entry = File.Exists(Path.Combine(directory, Configuration.EN5Entry)) ? Configuration.EN5Entry : Configuration.EN5Entry_New; var entryFileNameInExtractDirectory = $"{extractDirectory}\\{version}\\{entry}"; var enbxFileNameInExtractDirectory = $"{extractDirectory}\\{Path.GetFileName(enbxFileName)}"; var launcher = EN5Launcher.GenerateLauncher(entryFileNameInExtractDirectory); var dotNetInstaller = $"{extractDirectory}\\{version}\\{Configuration.DotNetInstaller}"; // 3. zip the Working Directory and the *.enbx file using (var zip = new ZipFile()) { //zip.Comment = AppInfo.Current.Description; zip.Password = EncryptHelper.Decrypt(Configuration.Password); zip.SaveProgress += Zip_SaveProgress; zip.AlternateEncoding = Encoding.UTF8; zip.AlternateEncodingUsage = ZipOption.AsNecessary; zip.AddFile(launcher, $"{AppInfo.Current.Version}"); zip.AddFile(enbxFileName, ""); zip.AddDirectory(directory, version); var options = new SelfExtractorSaveOptions { Flavor = SelfExtractorFlavor.ConsoleApplication, //RemoveUnpackedFilesAfterExecute = true }; var fileIcon = $"{AppDomain.CurrentDomain.BaseDirectory}\\{Configuration.EN5FileIconName}"; if (!string.IsNullOrEmpty(fileIcon) && File.Exists(fileIcon)) { options.IconFile = fileIcon; } // exe file info options.ProductName = AppInfo.Current.Name; options.Description = AppInfo.Current.Description; options.Copyright = AppInfo.Current.Copyright; options.ProductVersion = AppInfo.Current.Version; // player version options.FileVersion = new Version(version); // EasiNote5 verion // extract var launcherInExtract = $"{extractDirectory}\\{AppInfo.Current.Version}\\{Path.GetFileName(launcher)}"; var parameters = $"\"{enbxFileNameInExtractDirectory}\" \"{dotNetInstaller}\""; options.DefaultExtractDirectory = extractDirectory; options.PostExtractCommandLine = $"{launcherInExtract} {parameters}"; options.ExtractExistingFile = ExtractExistingFileAction.DoNotOverwrite; // zip zip.SaveSelfExtractor(outputFileName, options); } }
public void SFX_RemoveFilesAfterUnpack_wi10682() { string subdir = "files"; string[] filesToZip; Dictionary <string, byte[]> checksums; CreateFilesAndChecksums(subdir, out filesToZip, out checksums); string password = Path.GetFileNameWithoutExtension(Path.GetRandomFileName()); string postExeFormat = "post-extract-{0:D4}.exe"; string postExtractExe = String.Format(postExeFormat, _rnd.Next(10000)); CompileApp(0, postExtractExe); // pass 1 to run SFX and verify files are present; // pass 2 to run SFX and verify that it deletes files after extracting. // 2 passes: one for no cmd line overload, one with overload of -r+/-r- for (int j = 0; j < 2; j++) { // 2 passes: with RemoveUnpackedFiles set or unset for (int k = 0; k < 2; k++) { string sfxFileToCreate = String.Format("SFX_RemoveFilesAfterUnpack.{0}.{1}.exe", j, k); using (ZipFile zip = new ZipFile()) { zip.Password = password; zip.Encryption = Ionic.Zip.EncryptionAlgorithm.WinZipAes256; Array.ForEach(filesToZip, x => { zip.AddFile(x, "files"); }); zip.AddFile(postExtractExe, "files"); var sfxOptions = new SelfExtractorSaveOptions { Flavor = SelfExtractorFlavor.ConsoleApplication, Quiet = true, PostExtractCommandLine = Path.Combine("files", postExtractExe) }; if (k == 1) { sfxOptions.RemoveUnpackedFilesAfterExecute = true; } zip.SaveSelfExtractor(sfxFileToCreate, sfxOptions); } string extractDir = String.Format("extract.{0}.{1}", j, k); string sfxCmdLineArgs = String.Format("-p {0} -d {1}", password, extractDir); if (j == 1) { // override the option set at time of zip.SaveSfx() sfxCmdLineArgs += (k == 0) ? " -r+" : " -r-"; } // invoke the SFX this.Exec(sfxFileToCreate, sfxCmdLineArgs, true, true); if (k == j) { // verify that the files are extracted, and match VerifyChecksums(Path.Combine(extractDir, "files"), filesToZip, checksums); } else { // verify that no files exist in the extract directory var remainingFiles = Directory.GetFiles(extractDir); Assert.IsTrue(remainingFiles.Length == 0); } } } }
public void _Internal_SelfExtractor_Command(string cmdFormat, SelfExtractorFlavor flavor, bool runSfx, bool quiet, bool forceNoninteractive, bool wantArgs) { TestContext.WriteLine("=============================="); TestContext.WriteLine("SFX_RunOnExit({0})", flavor.ToString()); //int entriesAdded = 0; //String filename = null; string postExtractExe = String.Format(cmdFormat, _rnd.Next(3000)); // If WinForms and want forceNoninteractive, have the post-extract-exe return 0, // else, select a random number. int expectedReturnCode = (forceNoninteractive && flavor == SelfExtractorFlavor.WinFormsApplication) ? 0 : _rnd.Next(1024) + 20; TestContext.WriteLine("The post-extract command ({0}) will return {1}", postExtractExe, expectedReturnCode); string subdir = "A"; string[] filesToZip; Dictionary <string, byte[]> checksums; CreateFilesAndChecksums(subdir, out filesToZip, out checksums); for (int k = 0; k < 2; k++) { string readmeString = String.Format("Hey! This zipfile entry was created directly from " + "a string in application code. Flavor ({0}) Trial({1})", flavor.ToString(), k); string exeFileToCreate = String.Format("SFX_Command.{0}.{1}.exe", flavor.ToString(), k); TestContext.WriteLine("----------------------"); TestContext.WriteLine("Trial {0}", k); string unpackDir = String.Format("unpack.{0}", k); var sw = new System.IO.StringWriter(); using (ZipFile zip = new ZipFile()) { zip.StatusMessageTextWriter = sw; zip.AddDirectory(subdir, subdir); // Path.GetFileName(subdir)); zip.Comment = String.Format("Trial options: fl({0}) cmd ({3})\r\n" + "actuallyRun({1})\r\nquiet({2})\r\n" + "exists? {4}\r\nexpected rc={5}", flavor, runSfx, quiet, postExtractExe, k != 0, expectedReturnCode ); var ms1 = new MemoryStream(Encoding.UTF8.GetBytes(readmeString)); zip.AddEntry("Readme.txt", ms1); if (k != 0) { CompileApp(expectedReturnCode, postExtractExe); zip.AddFile(postExtractExe); } var sfxOptions = new SelfExtractorSaveOptions { Flavor = flavor, DefaultExtractDirectory = unpackDir, SfxExeWindowTitle = "Custom SFX Title " + DateTime.Now.ToString("G"), Quiet = quiet }; // In the case of k==0, this exe does not exist. It will result in // a return code of 5. In k == 1, the exe exists and will succeed. if (postExtractExe.Contains(' ')) { sfxOptions.PostExtractCommandLine = "\"" + postExtractExe + "\""; } else { sfxOptions.PostExtractCommandLine = postExtractExe; } if (wantArgs) { sfxOptions.PostExtractCommandLine += " arg1 arg2"; } zip.SaveSelfExtractor(exeFileToCreate, sfxOptions); } TestContext.WriteLine("status output: " + sw.ToString()); if (k != 0) { File.Delete(postExtractExe); } // Run the generated Self-extractor, conditionally. // // We always run, unless specifically asked not to, OR if it's a // winforms app and we want it to be noninteractive and there's no // EXE to run. If we try running a non-existent app, it will pop an // error message, hence user interaction, which we need to avoid for // the automated test. if (runSfx && (k != 0 || !forceNoninteractive || flavor != SelfExtractorFlavor.WinFormsApplication)) { TestContext.WriteLine("Running the SFX... "); System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(exeFileToCreate); psi.WorkingDirectory = TopLevelDir; psi.UseShellExecute = false; psi.CreateNoWindow = true; // false; System.Diagnostics.Process process = System.Diagnostics.Process.Start(psi); process.WaitForExit(); int rc = process.ExitCode; TestContext.WriteLine("SFX exit code: ({0})", rc); // The exit code is returned only if it's a console SFX. if (flavor == SelfExtractorFlavor.ConsoleApplication) { // The program actually runs if k != 0 if (k == 0) { // The file to execute should not have been found, hence rc==5. Assert.AreEqual <Int32> (5, rc, "In trial {0}, the exit code was unexpected.", k); } else { // The file to execute should have returned a specific code. Assert.AreEqual <Int32> (expectedReturnCode, rc, "In trial {0}, the exit code did not match.", k); } } else { Assert.AreEqual <Int32>(0, rc, "In trial {0}, the exit code did not match.", k); } VerifyChecksums(Path.Combine(unpackDir, "A"), filesToZip, checksums); } } }