private void createSelfExtractingZip(MyFile mf)
 {
     try {
         NetworkDrives.MapDrive("iboxx");                                                                          //comment for local testing 3/26
         using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile()) {
             if (mf.IsFolder)
             {
                 zip.AddDirectory(mf.From);
             }
             else
             {
                 zip.AddFile(mf.From);
             }
             Ionic.Zip.SelfExtractorSaveOptions options = new Ionic.Zip.SelfExtractorSaveOptions();
             options.Flavor = Ionic.Zip.SelfExtractorFlavor.ConsoleApplication;
             zip.SaveSelfExtractor(mf.FullName, options);
         }
         NetworkDrives.DisconnectDrive("iboxx");                                                                   //comment for local testing
     } catch (Exception e) {
         displayError(e);
         throw;
         //if (Error == "") {
         //    Error = "Error caught in createSelfExtractingZip() " + e;
         //    throw;
         //}
         ////ScriptManager.RegisterStartupScript(this.Page, Page.GetType(), "Message", "<script>alert('Error caught in createSelfExtractingZip() " + e + "');</script>", true);
         ////this.Response.Write("<script>alert('Error caught in createSelfExtractingZip() " + e + "');</script>");
     }
 }
        /// <summary>
        /// Create a self-extracting ZIP using the DoNetZip library
        /// </summary>
        public static void CreateSelfExtractingZip(string outputFile, string tempFilePath, string productVersion, string productDescription, string installPath, string postExtractCommand)
        {
            if (!String.IsNullOrEmpty(outputFile))
            {
                using (var zip = new ZipFile())
                {
                    zip.AddDirectory(tempFilePath);

                    var options = new SelfExtractorSaveOptions
                    {
                        ProductName = productDescription,
                        ProductVersion = productVersion,
                        FileVersion = new System.Version(productVersion),
                        Description = productDescription,
                        Copyright = "Copyright © Influence Health 2015",
                        DefaultExtractDirectory = installPath,
                        Flavor = SelfExtractorFlavor.WinFormsApplication,
                        Quiet = false,
                        RemoveUnpackedFilesAfterExecute = false,
                        IconFile = Environment.CurrentDirectory + @"\Installer.ico",
                        ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently,
                        PostExtractCommandLine = postExtractCommand
                    };
                    zip.SaveSelfExtractor(outputFile, options);
                }
            }
        }
        //string _defaultExtractLocation;
        //string _postExtractCmdLine;
        //         string _SetDefaultLocationCode =
        //         "namespace Ionic.Zip { public partial class WinFormsSelfExtractorStub { partial void _SetDefaultExtractLocation() {" +
        //         " txtExtractDirectory.Text = \"@@VALUE\"; } }}";



        /// <summary>
        /// Saves the ZipFile instance to a self-extracting zip archive.
        /// </summary>
        ///
        /// <remarks>
        ///
        /// <para>
        /// The generated exe image will execute on any machine that has the .NET
        /// Framework 2.0 installed on it.  The generated exe image is also a
        /// valid ZIP file, readable with DotNetZip or another Zip library or tool
        /// such as WinZip.
        /// </para>
        ///
        /// <para>
        /// There are two "flavors" of self-extracting archive.  The
        /// <c>WinFormsApplication</c> version will pop up a GUI and allow the
        /// user to select a target directory into which to extract. There's also
        /// a checkbox allowing the user to specify to overwrite existing files,
        /// and another checkbox to allow the user to request that Explorer be
        /// opened to see the extracted files after extraction.  The other flavor
        /// is <c>ConsoleApplication</c>.  A self-extractor generated with that
        /// flavor setting will run from the command line. It accepts command-line
        /// options to set the overwrite behavior, and to specify the target
        /// extraction directory.
        /// </para>
        ///
        /// <para>
        /// There are a few temporary files created during the saving to a
        /// self-extracting zip.  These files are created in the directory pointed
        /// to by <see cref="ZipFile.TempFileFolder"/>, which defaults to <see
        /// cref="System.IO.Path.GetTempPath"/>.  These temporary files are
        /// removed upon successful completion of this method.
        /// </para>
        ///
        /// <para>
        /// When a user runs the WinForms SFX, the user's personal directory (<see
        /// cref="Environment.SpecialFolder.Personal">Environment.SpecialFolder.Personal</see>)
        /// will be used as the default extract location.  If you want to set the
        /// default extract location, you should use the other overload of
        /// <c>SaveSelfExtractor()</c>/ The user who runs the SFX will have the
        /// opportunity to change the extract directory before extracting. When
        /// the user runs the Command-Line SFX, the user must explicitly specify
        /// the directory to which to extract.  The .NET Framework 2.0 is required
        /// on the computer when the self-extracting archive is run.
        /// </para>
        ///
        /// <para>
        /// NB: This method is not available in the version of DotNetZip build for
        /// the .NET Compact Framework, nor in the "Reduced" DotNetZip library.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <example>
        /// <code>
        /// string DirectoryPath = "c:\\Documents\\Project7";
        /// using (ZipFile zip = new ZipFile())
        /// {
        ///     zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath));
        ///     zip.Comment = "This will be embedded into a self-extracting console-based exe";
        ///     zip.SaveSelfExtractor("archive.exe", SelfExtractorFlavor.ConsoleApplication);
        /// }
        /// </code>
        /// <code lang="VB">
        /// Dim DirectoryPath As String = "c:\Documents\Project7"
        /// Using zip As New ZipFile()
        ///     zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath))
        ///     zip.Comment = "This will be embedded into a self-extracting console-based exe"
        ///     zip.SaveSelfExtractor("archive.exe", SelfExtractorFlavor.ConsoleApplication)
        /// End Using
        /// </code>
        /// </example>
        ///
        /// <param name="exeToGenerate">
        ///   a pathname, possibly fully qualified, to be created. Typically it
        ///   will end in an .exe extension.</param>
        /// <param name="flavor">
        ///   Indicates whether a Winforms or Console self-extractor is
        ///   desired. </param>
        public void SaveSelfExtractor(string exeToGenerate, SelfExtractorFlavor flavor)
        {
            SelfExtractorSaveOptions options = new SelfExtractorSaveOptions();

            options.Flavor = flavor;
            SaveSelfExtractor(exeToGenerate, options);
        }
        /// <summary>
        ///   Saves the ZipFile instance to a self-extracting zip archive, using
        ///   the specified save options.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   This method saves a self extracting archive, using the specified save
        ///   options. These options include the flavor of the SFX, the default extract
        ///   directory, the icon file, and so on.  See the documentation
        ///   for <see cref="SaveSelfExtractor(string , SelfExtractorFlavor)"/> for more
        ///   details.
        /// </para>
        ///
        /// <para>
        ///   The user who runs the SFX will have the opportunity to change the extract
        ///   directory before extracting. If at the time of extraction, the specified
        ///   directory does not exist, the SFX will create the directory before
        ///   extracting the files.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <example>
        ///   This example saves a WinForms-based self-extracting archive EXE that
        ///   will use c:\ExtractHere as the default extract location. The C# code
        ///   shows syntax for .NET 3.0, which uses an object initializer for
        ///   the SelfExtractorOptions object.
        /// <code>
        /// string DirectoryPath = "c:\\Documents\\Project7";
        /// using (ZipFile zip = new ZipFile())
        /// {
        ///     zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath));
        ///     zip.Comment = "This will be embedded into a self-extracting WinForms-based exe";
        ///     var options = new SelfExtractorOptions
        ///     {
        ///       Flavor = SelfExtractorFlavor.WinFormsApplication,
        ///       DefaultExtractDirectory = "%USERPROFILE%\\ExtractHere",
        ///       PostExtractCommandLine = ExeToRunAfterExtract,
        ///       SfxExeWindowTitle = "My Custom Window Title",
        ///       RemoveUnpackedFilesAfterExecute = true
        ///     };
        ///     zip.SaveSelfExtractor("archive.exe", options);
        /// }
        /// </code>
        /// <code lang="VB">
        /// Dim DirectoryPath As String = "c:\Documents\Project7"
        /// Using zip As New ZipFile()
        ///     zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath))
        ///     zip.Comment = "This will be embedded into a self-extracting console-based exe"
        ///     Dim options As New SelfExtractorOptions()
        ///     options.Flavor = SelfExtractorFlavor.WinFormsApplication
        ///     options.DefaultExtractDirectory = "%USERPROFILE%\\ExtractHere"
        ///     options.PostExtractCommandLine = ExeToRunAfterExtract
        ///     options.SfxExeWindowTitle = "My Custom Window Title"
        ///     options.RemoveUnpackedFilesAfterExecute = True
        ///     zip.SaveSelfExtractor("archive.exe", options)
        /// End Using
        /// </code>
        /// </example>
        ///
        /// <param name="exeToGenerate">The name of the EXE to generate.</param>
        /// <param name="options">provides the options for creating the
        /// Self-extracting archive.</param>
        public void SaveSelfExtractor(string exeToGenerate, SelfExtractorSaveOptions options)
        {
            // Save an SFX that is both an EXE and a ZIP.

            // Check for the case where we are re-saving a zip archive
            // that was originally instantiated with a stream.  In that case,
            // the _name will be null. If so, we set _writestream to null,
            // which insures that we'll cons up a new WriteStream (with a filesystem
            // file backing it) in the Save() method.
            if (_name == null)
            {
                _writestream = null;
            }

            _SavingSfx = true;
            _name      = exeToGenerate;
            if (Directory.Exists(_name))
            {
                throw new ZipException("Bad Directory", new System.ArgumentException("That name specifies an existing directory. Please specify a filename.", "exeToGenerate"));
            }
            _contentsChanged   = true;
            _fileAlreadyExists = File.Exists(_name);

            _SaveSfxStub(exeToGenerate, options);

            Save();
            _SavingSfx = false;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (!created)
            {
                string DirectoryPath = @"C:\SOURCE\DSPControlCenter\Setup\Setup\Express\SingleImage\DiskImages\DISK1";
                using (ZipFile zip = new ZipFile())
                {
                    zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath));
                    zip.Comment = "This will be embedded into a self-extracting console-based exe";
                    SelfExtractorSaveOptions options = new SelfExtractorSaveOptions();
                    options.Flavor = SelfExtractorFlavor.ConsoleApplication;
                    options.Quiet = true;
                    options.DefaultExtractDirectory = "%TEMP%\\DSPCC";
                    options.PostExtractCommandLine = "%TEMP%\\DSPCC\\DISK1\\setup.exe";
                    options.RemoveUnpackedFilesAfterExecute = true;
                    options.FileVersion = new Version(2, 1, 0);
                    options.Description = "DSP Control Center Installer Package";
                    options.Copyright = "© 2013 Stewart Audio, Inc.";
                    options.IconFile = @"C:\SOURCE\DSPControlCenter\DSP Control Center v4.ico";
                    options.ProductName = "DSP Control Center";
                    options.ProductVersion = "2.1.0";
                    options.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;
                    zip.SaveSelfExtractor(txtFilename.Text + " v" + txtVersion.Text + ".exe", options);

                    button1.Text = "Open Folder";

                    created = true;
                }
            } else
            {
                string myPath = @"C:\SOURCE\DSPControlCenter\Setup\SetupLauncher\SetupLauncher\bin\Debug";
                System.Diagnostics.Process prc = new System.Diagnostics.Process();
                prc.StartInfo.FileName = myPath;
                prc.Start();
            }
        }
Exemple #6
0
        public void run()
        {
            logger.Info("Making archive [what's it called?]");

            using (ZipFile zip = new ZipFile())
            {
                if (Directory.Exists(SourceDir))
                {
                    zip.AddDirectory(SourceDir, Path.GetFileName(SourceDir));
                }
                else
                {
                    // logger?
                    Console.WriteLine("{0} is not a valid directory", SourceDir);
                    Environment.Exit(1);
                }

                // these files install and log the patch
                zip.AddFile("Clyde.exe");
                zip.AddFile("PatchLib.dll");
                zip.AddFile("Nini.dll");
                zip.AddFile("NLog.dll");
                zip.AddFile("NLog.config");

                SelfExtractorSaveOptions options = new SelfExtractorSaveOptions();
                options.Flavor = SelfExtractorFlavor.ConsoleApplication;
                options.ProductVersion = VersionInfo.PRODUCT_VERSION;
                options.DefaultExtractDirectory = ExtractDir;
                options.Copyright = VersionInfo.COPYRIGHT;
                options.PostExtractCommandLine = "Clyde.exe";
                // false for dev, (maybe) true for production
                options.RemoveUnpackedFilesAfterExecute = false;

                string patchName = @"envision-installer-" + PatchVersion + @".exe";
                zip.SaveSelfExtractor(patchName, options);
            }
        }
        private void _SaveSfxStub(string exeToGenerate, SelfExtractorSaveOptions options)
        {
            string nameOfIconFile      = null;
            string stubExe             = null;
            string unpackedResourceDir = null;
            string tmpDir = null;

            try
            {
                if (File.Exists(exeToGenerate))
                {
                    if (Verbose)
                    {
                        StatusMessageTextWriter.WriteLine("The existing file ({0}) will be overwritten.", exeToGenerate);
                    }
                }
                if (!exeToGenerate.EndsWith(".exe"))
                {
                    if (Verbose)
                    {
                        StatusMessageTextWriter.WriteLine("Warning: The generated self-extracting file will not have an .exe extension.");
                    }
                }

                // workitem 10553
                tmpDir  = TempFileFolder ?? Path.GetDirectoryName(exeToGenerate);
                stubExe = GenerateTempPathname(tmpDir, "exe");

                // get the Ionic.Zip assembly
                Assembly a1 = typeof(ZipFile).Assembly;

                using (var csharp = new Microsoft.CSharp.CSharpCodeProvider
                                        (new Dictionary <string, string>()
                {
                    { "CompilerVersion", "v2.0" }
                })) {
                    // The following is a perfect opportunity for a linq query, but
                    // I cannot use it.  DotNetZip needs to run on .NET 2.0,
                    // and using LINQ would break that. Here's what it would look
                    // like:
                    //
                    //   var settings = (from x in SettingsList
                    //                   where x.Flavor == flavor
                    //                   select x).First();

                    ExtractorSettings settings = null;
                    foreach (var x in SettingsList)
                    {
                        if (x.Flavor == options.Flavor)
                        {
                            settings = x;
                            break;
                        }
                    }

                    // sanity check; should never happen
                    if (settings == null)
                    {
                        throw new BadStateException(String.Format("While saving a Self-Extracting Zip, Cannot find that flavor ({0})?", options.Flavor));
                    }

                    // This is the list of referenced assemblies.  Ionic.Zip is
                    // needed here.  Also if it is the winforms (gui) extractor, we
                    // need other referenced assemblies, like
                    // System.Windows.Forms.dll, etc.
                    var cp = new System.CodeDom.Compiler.CompilerParameters();
                    cp.ReferencedAssemblies.Add(a1.Location);
                    if (settings.ReferencedAssemblies != null)
                    {
                        foreach (string ra in settings.ReferencedAssemblies)
                        {
                            cp.ReferencedAssemblies.Add(ra);
                        }
                    }

                    cp.GenerateInMemory        = false;
                    cp.GenerateExecutable      = true;
                    cp.IncludeDebugInformation = false;
                    cp.CompilerOptions         = "";

                    Assembly a2 = Assembly.GetExecutingAssembly();

                    // Use this to concatenate all the source code resources into a
                    // single module.
                    var sb = new System.Text.StringBuilder();

                    // In case there are compiler errors later, we allocate a source
                    // file name now. If errors are detected, we'll spool the source
                    // code as well as the errors (in comments) into that filename,
                    // and throw an exception with the filename.  Makes it easier to
                    // diagnose.  This should be rare; most errors happen only
                    // during devlpmt of DotNetZip itself, but there are rare
                    // occasions when they occur in other cases.
                    string sourceFile = GenerateTempPathname(tmpDir, "cs");


                    // // debugging: enumerate the resources in this assembly
                    // Console.WriteLine("Resources in this assembly:");
                    // foreach (string rsrc in a2.GetManifestResourceNames())
                    //   {
                    //     Console.WriteLine(rsrc);
                    //   }
                    // Console.WriteLine();


                    // all the source code is embedded in the DLL as a zip file.
                    using (ZipFile zip = ZipFile.Read(a2.GetManifestResourceStream("Ionic.Zip.Resources.ZippedResources.zip")))
                    {
                        // // debugging: enumerate the files in the embedded zip
                        // Console.WriteLine("Entries in the embbedded zip:");
                        // foreach (ZipEntry entry in zip)
                        //   {
                        //     Console.WriteLine(entry.FileName);
                        //   }
                        // Console.WriteLine();

                        unpackedResourceDir = GenerateTempPathname(tmpDir, "tmp");

                        if (String.IsNullOrEmpty(options.IconFile))
                        {
                            // Use the ico file that is embedded into the Ionic.Zip
                            // DLL itself.  To do this we must unpack the icon to
                            // the filesystem, in order to specify it on the cmdline
                            // of csc.exe.  This method will remove the unpacked
                            // file later.
                            System.IO.Directory.CreateDirectory(unpackedResourceDir);
                            ZipEntry e = zip["zippedFile.ico"];
                            // Must not extract a readonly file - it will be impossible to
                            // delete later.
                            if ((e.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                            {
                                e.Attributes ^= FileAttributes.ReadOnly;
                            }
                            e.Extract(unpackedResourceDir);
                            nameOfIconFile      = Path.Combine(unpackedResourceDir, "zippedFile.ico");
                            cp.CompilerOptions += String.Format("/win32icon:\"{0}\"", nameOfIconFile);
                        }
                        else
                        {
                            cp.CompilerOptions += String.Format("/win32icon:\"{0}\"", options.IconFile);
                        }

                        cp.OutputAssembly = stubExe;

                        if (options.Flavor == SelfExtractorFlavor.WinFormsApplication)
                        {
                            cp.CompilerOptions += " /target:winexe";
                        }

                        if (!String.IsNullOrEmpty(options.AdditionalCompilerSwitches))
                        {
                            cp.CompilerOptions += " " + options.AdditionalCompilerSwitches;
                        }

                        if (String.IsNullOrEmpty(cp.CompilerOptions))
                        {
                            cp.CompilerOptions = null;
                        }

                        if ((settings.CopyThroughResources != null) && (settings.CopyThroughResources.Count != 0))
                        {
                            if (!Directory.Exists(unpackedResourceDir))
                            {
                                System.IO.Directory.CreateDirectory(unpackedResourceDir);
                            }
                            foreach (string re in settings.CopyThroughResources)
                            {
                                string filename = Path.Combine(unpackedResourceDir, re);

                                ExtractResourceToFile(a2, re, filename);
                                // add the file into the target assembly as an embedded resource
                                cp.EmbeddedResources.Add(filename);
                            }
                        }

                        // add the Ionic.Utils.Zip DLL as an embedded resource
                        cp.EmbeddedResources.Add(a1.Location);

                        // file header
                        sb.Append("// " + Path.GetFileName(sourceFile) + "\n")
                        .Append("// --------------------------------------------\n//\n")
                        .Append("// This SFX source file was generated by DotNetZip ")
                        .Append(ZipFile.LibraryVersion.ToString())
                        .Append("\n//         at ")
                        .Append(System.DateTime.Now.ToString("yyyy MMMM dd  HH:mm:ss"))
                        .Append("\n//\n// --------------------------------------------\n\n\n");

                        // assembly attributes
                        if (!String.IsNullOrEmpty(options.Description))
                        {
                            sb.Append("[assembly: System.Reflection.AssemblyTitle(\""
                                      + options.Description.Replace("\"", "")
                                      + "\")]\n");
                        }
                        else
                        {
                            sb.Append("[assembly: System.Reflection.AssemblyTitle(\"DotNetZip SFX Archive\")]\n");
                        }

                        if (!String.IsNullOrEmpty(options.ProductVersion))
                        {
                            sb.Append("[assembly: System.Reflection.AssemblyInformationalVersion(\""
                                      + options.ProductVersion.Replace("\"", "")
                                      + "\")]\n");
                        }

                        // workitem
                        string copyright =
                            (String.IsNullOrEmpty(options.Copyright))
                            ? "Extractor: Copyright © Dino Chiesa 2008-2011"
                            : options.Copyright.Replace("\"", "");

                        if (!String.IsNullOrEmpty(options.ProductName))
                        {
                            sb.Append("[assembly: System.Reflection.AssemblyProduct(\"")
                            .Append(options.ProductName.Replace("\"", ""))
                            .Append("\")]\n");
                        }
                        else
                        {
                            sb.Append("[assembly: System.Reflection.AssemblyProduct(\"DotNetZip\")]\n");
                        }


                        sb.Append("[assembly: System.Reflection.AssemblyCopyright(\"" + copyright + "\")]\n")
                        .Append(String.Format("[assembly: System.Reflection.AssemblyVersion(\"{0}\")]\n", ZipFile.LibraryVersion.ToString()));
                        if (options.FileVersion != null)
                        {
                            sb.Append(String.Format("[assembly: System.Reflection.AssemblyFileVersion(\"{0}\")]\n",
                                                    options.FileVersion.ToString()));
                        }

                        sb.Append("\n\n\n");

                        // Set the default extract location if it is available
                        string extractLoc = options.DefaultExtractDirectory;
                        if (extractLoc != null)
                        {
                            // remove double-quotes and replace slash with double-slash.
                            // This, because the value is going to be embedded into a
                            // cs file as a quoted string, and it needs to be escaped.
                            extractLoc = extractLoc.Replace("\"", "").Replace("\\", "\\\\");
                        }

                        string postExCmdLine = options.PostExtractCommandLine;
                        if (postExCmdLine != null)
                        {
                            postExCmdLine = postExCmdLine.Replace("\\", "\\\\");
                            postExCmdLine = postExCmdLine.Replace("\"", "\\\"");
                        }


                        foreach (string rc in settings.ResourcesToCompile)
                        {
                            using (Stream s = zip[rc].OpenReader())
                            {
                                if (s == null)
                                {
                                    throw new ZipException(String.Format("missing resource '{0}'", rc));
                                }
                                using (StreamReader sr = new StreamReader(s))
                                {
                                    while (sr.Peek() >= 0)
                                    {
                                        string line = sr.ReadLine();
                                        if (extractLoc != null)
                                        {
                                            line = line.Replace("@@EXTRACTLOCATION", extractLoc);
                                        }

                                        line = line.Replace("@@REMOVE_AFTER_EXECUTE", options.RemoveUnpackedFilesAfterExecute.ToString());
                                        line = line.Replace("@@QUIET", options.Quiet.ToString());
                                        if (!String.IsNullOrEmpty(options.SfxExeWindowTitle))
                                        {
                                            line = line.Replace("@@SFX_EXE_WINDOW_TITLE", options.SfxExeWindowTitle);
                                        }

                                        line = line.Replace("@@EXTRACT_EXISTING_FILE", ((int)options.ExtractExistingFile).ToString());

                                        if (postExCmdLine != null)
                                        {
                                            line = line.Replace("@@POST_UNPACK_CMD_LINE", postExCmdLine);
                                        }

                                        sb.Append(line).Append("\n");
                                    }
                                }
                                sb.Append("\n\n");
                            }
                        }
                    }

                    string LiteralSource = sb.ToString();

#if DEBUGSFX
                    // for debugging only
                    string sourceModule = GenerateTempPathname(tmpDir, "cs");
                    using (StreamWriter sw = File.CreateText(sourceModule))
                    {
                        sw.Write(LiteralSource);
                    }
                    Console.WriteLine("source: {0}", sourceModule);
#endif

                    var cr = csharp.CompileAssemblyFromSource(cp, LiteralSource);


                    if (cr == null)
                    {
                        throw new SfxGenerationException("Cannot compile the extraction logic!");
                    }

                    if (Verbose)
                    {
                        foreach (string output in cr.Output)
                        {
                            StatusMessageTextWriter.WriteLine(output);
                        }
                    }

                    if (cr.Errors.Count != 0)
                    {
                        using (var sourceFileStream = new FileStream(sourceFile, FileMode.Create))
                            using (TextWriter tw = new StreamWriter(sourceFileStream))
                            {
                                // first, the source we compiled
                                tw.Write(LiteralSource);

                                // now, append the compile errors
                                tw.Write("\n\n\n// ------------------------------------------------------------------\n");
                                tw.Write("// Errors during compilation: \n//\n");
                                string p = Path.GetFileName(sourceFile);

                                foreach (System.CodeDom.Compiler.CompilerError error in cr.Errors)
                                {
                                    tw.Write(String.Format("//   {0}({1},{2}): {3} {4}: {5}\n//\n",
                                                           p,                                     // 0
                                                           error.Line,                            // 1
                                                           error.Column,                          // 2
                                                           error.IsWarning ? "Warning" : "error", // 3
                                                           error.ErrorNumber,                     // 4
                                                           error.ErrorText));                     // 5
                                }
                            }
                        throw new SfxGenerationException(String.Format("Errors compiling the extraction logic!  {0}", sourceFile));
                    }

                    OnSaveEvent(ZipProgressEventType.Saving_AfterCompileSelfExtractor);

                    // Now, copy the resulting EXE image to the _writestream.
                    // Because this stub exe is being saved first, the effect will be to
                    // concatenate the exe and the zip data together.
                    using (System.IO.Stream input = System.IO.File.OpenRead(stubExe))
                    {
                        byte[] buffer = new byte[4000];
                        int    n      = 1;
                        while (n != 0)
                        {
                            n = input.Read(buffer, 0, buffer.Length);
                            if (n != 0)
                            {
                                WriteStream.Write(buffer, 0, n);
                            }
                        }
                    }
                }

                OnSaveEvent(ZipProgressEventType.Saving_AfterSaveTempArchive);
            }
            finally
            {
                try
                {
                    if (Directory.Exists(unpackedResourceDir))
                    {
                        try { Directory.Delete(unpackedResourceDir, true); }
                        catch (System.IO.IOException exc1)
                        {
                            StatusMessageTextWriter.WriteLine("Warning: Exception: {0}", exc1);
                        }
                    }
                    if (File.Exists(stubExe))
                    {
                        try { File.Delete(stubExe); }
                        catch (System.IO.IOException exc1)
                        {
                            StatusMessageTextWriter.WriteLine("Warning: Exception: {0}", exc1);
                        }
                    }
                }
                catch (System.IO.IOException) { }
            }

            return;
        }
        private void _SaveSfxStub(string exeToGenerate, SelfExtractorSaveOptions options)
        {
            string nameOfIconFile = null;
            string stubExe = null;
            string unpackedResourceDir = null;
            string tmpDir = null;
            try
            {
                if (File.Exists(exeToGenerate))
                {
                    if (Verbose) StatusMessageTextWriter.WriteLine("The existing file ({0}) will be overwritten.", exeToGenerate);
                }
                if (!exeToGenerate.EndsWith(".exe"))
                {
                    if (Verbose) StatusMessageTextWriter.WriteLine("Warning: The generated self-extracting file will not have an .exe extension.");
                }

                // workitem 10553
                tmpDir = TempFileFolder ?? Path.GetDirectoryName(exeToGenerate);
                stubExe = GenerateTempPathname(tmpDir, "exe");

                // get the Ionic.Zip assembly
                Assembly a1 = typeof(ZipFile).Assembly;

                using (var csharp = new Microsoft.CSharp.CSharpCodeProvider
                       (new Dictionary<string,string>() { { "CompilerVersion", "v2.0" } })) {

                    // The following is a perfect opportunity for a linq query, but
                    // I cannot use it.  DotNetZip needs to run on .NET 2.0,
                    // and using LINQ would break that. Here's what it would look
                    // like:
                    //
                    //   var settings = (from x in SettingsList
                    //                   where x.Flavor == flavor
                    //                   select x).First();

                    ExtractorSettings settings = null;
                    foreach (var x in SettingsList)
                    {
                        if (x.Flavor == options.Flavor)
                        {
                            settings = x;
                            break;
                        }
                    }

                    // sanity check; should never happen
                    if (settings == null)
                        throw new BadStateException(String.Format("While saving a Self-Extracting Zip, Cannot find that flavor ({0})?", options.Flavor));

                    // This is the list of referenced assemblies.  Ionic.Zip is
                    // needed here.  Also if it is the winforms (gui) extractor, we
                    // need other referenced assemblies, like
                    // System.Windows.Forms.dll, etc.
                    var cp = new System.CodeDom.Compiler.CompilerParameters();
                    cp.ReferencedAssemblies.Add(a1.Location);
                    if (settings.ReferencedAssemblies != null)
                        foreach (string ra in settings.ReferencedAssemblies)
                            cp.ReferencedAssemblies.Add(ra);

                    cp.GenerateInMemory = false;
                    cp.GenerateExecutable = true;
                    cp.IncludeDebugInformation = false;
                    cp.CompilerOptions = "";

                    Assembly a2 = Assembly.GetExecutingAssembly();

                    // Use this to concatenate all the source code resources into a
                    // single module.
                    var sb = new System.Text.StringBuilder();

                    // In case there are compiler errors later, we allocate a source
                    // file name now. If errors are detected, we'll spool the source
                    // code as well as the errors (in comments) into that filename,
                    // and throw an exception with the filename.  Makes it easier to
                    // diagnose.  This should be rare; most errors happen only
                    // during devlpmt of DotNetZip itself, but there are rare
                    // occasions when they occur in other cases.
                    string sourceFile = GenerateTempPathname(tmpDir, "cs");


                    // // debugging: enumerate the resources in this assembly
                    // Console.WriteLine("Resources in this assembly:");
                    // foreach (string rsrc in a2.GetManifestResourceNames())
                    //   {
                    //     Console.WriteLine(rsrc);
                    //   }
                    // Console.WriteLine();


                    // all the source code is embedded in the DLL as a zip file.
                    using (ZipFile zip = ZipFile.Read(a2.GetManifestResourceStream("Ionic.Zip.Resources.ZippedResources.zip")))
                    {
                        // // debugging: enumerate the files in the embedded zip
                        // Console.WriteLine("Entries in the embbedded zip:");
                        // foreach (ZipEntry entry in zip)
                        //   {
                        //     Console.WriteLine(entry.FileName);
                        //   }
                        // Console.WriteLine();

                        unpackedResourceDir = GenerateTempPathname(tmpDir, "tmp");

                        if (String.IsNullOrEmpty(options.IconFile))
                        {
                            // Use the ico file that is embedded into the Ionic.Zip
                            // DLL itself.  To do this we must unpack the icon to
                            // the filesystem, in order to specify it on the cmdline
                            // of csc.exe.  This method will remove the unpacked
                            // file later.
                            System.IO.Directory.CreateDirectory(unpackedResourceDir);
                            ZipEntry e = zip["zippedFile.ico"];
                            // Must not extract a readonly file - it will be impossible to
                            // delete later.
                            if ((e.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                                e.Attributes ^= FileAttributes.ReadOnly;
                            e.Extract(unpackedResourceDir);
                            nameOfIconFile = Path.Combine(unpackedResourceDir, "zippedFile.ico");
                            cp.CompilerOptions += String.Format("/win32icon:\"{0}\"", nameOfIconFile);
                        }
                        else
                            cp.CompilerOptions += String.Format("/win32icon:\"{0}\"", options.IconFile);

                        cp.OutputAssembly = stubExe;

                        if (options.Flavor == SelfExtractorFlavor.WinFormsApplication)
                            cp.CompilerOptions += " /target:winexe";

                        if (!String.IsNullOrEmpty(options.AdditionalCompilerSwitches))
                            cp.CompilerOptions += " " + options.AdditionalCompilerSwitches;

                        if (String.IsNullOrEmpty(cp.CompilerOptions))
                            cp.CompilerOptions = null;

                        if ((settings.CopyThroughResources != null) && (settings.CopyThroughResources.Count != 0))
                        {
                            if (!Directory.Exists(unpackedResourceDir)) System.IO.Directory.CreateDirectory(unpackedResourceDir);
                            foreach (string re in settings.CopyThroughResources)
                            {
                                string filename = Path.Combine(unpackedResourceDir, re);

                                ExtractResourceToFile(a2, re, filename);
                                // add the file into the target assembly as an embedded resource
                                cp.EmbeddedResources.Add(filename);
                            }
                        }

                        // add the Ionic.Utils.Zip DLL as an embedded resource
                        cp.EmbeddedResources.Add(a1.Location);

                        // file header
                        sb.Append("// " + Path.GetFileName(sourceFile) + "\n")
                            .Append("// --------------------------------------------\n//\n")
                            .Append("// This SFX source file was generated by DotNetZip ")
                            .Append(ZipFile.LibraryVersion.ToString())
                            .Append("\n//         at ")
                            .Append(System.DateTime.Now.ToString("yyyy MMMM dd  HH:mm:ss"))
                            .Append("\n//\n// --------------------------------------------\n\n\n");

                        // assembly attributes
                        if (!String.IsNullOrEmpty(options.Description))
                            sb.Append("[assembly: System.Reflection.AssemblyTitle(\""
                                      + options.Description.Replace("\"", "")
                                      + "\")]\n");
                        else
                            sb.Append("[assembly: System.Reflection.AssemblyTitle(\"DotNetZip SFX Archive\")]\n");

                        if (!String.IsNullOrEmpty(options.ProductVersion))
                            sb.Append("[assembly: System.Reflection.AssemblyInformationalVersion(\""
                                      + options.ProductVersion.Replace("\"", "")
                                      + "\")]\n");

                        // workitem
                        string copyright =
                            (String.IsNullOrEmpty(options.Copyright))
                            ? "Extractor: Copyright © Dino Chiesa 2008-2011"
                            : options.Copyright.Replace("\"", "");

                        if (!String.IsNullOrEmpty(options.ProductName))
                            sb.Append("[assembly: System.Reflection.AssemblyProduct(\"")
                                .Append(options.ProductName.Replace("\"", ""))
                                .Append("\")]\n");
                        else
                            sb.Append("[assembly: System.Reflection.AssemblyProduct(\"DotNetZip\")]\n");


                        sb.Append("[assembly: System.Reflection.AssemblyCopyright(\"" + copyright + "\")]\n")
                            .Append(String.Format("[assembly: System.Reflection.AssemblyVersion(\"{0}\")]\n", ZipFile.LibraryVersion.ToString()));
                        if (options.FileVersion != null)
                            sb.Append(String.Format("[assembly: System.Reflection.AssemblyFileVersion(\"{0}\")]\n",
                                                    options.FileVersion.ToString()));

                        sb.Append("\n\n\n");

                        // Set the default extract location if it is available
                        string extractLoc = options.DefaultExtractDirectory;
                        if (extractLoc != null)
                        {
                            // remove double-quotes and replace slash with double-slash.
                            // This, because the value is going to be embedded into a
                            // cs file as a quoted string, and it needs to be escaped.
                            extractLoc = extractLoc.Replace("\"", "").Replace("\\", "\\\\");
                        }

                        string postExCmdLine = options.PostExtractCommandLine;
                        if (postExCmdLine != null)
                        {
                            postExCmdLine = postExCmdLine.Replace("\\", "\\\\");
                            postExCmdLine = postExCmdLine.Replace("\"", "\\\"");
                        }


                        foreach (string rc in settings.ResourcesToCompile)
                        {
                            using (Stream s = zip[rc].OpenReader())
                            {
                                if (s == null)
                                    throw new ZipException(String.Format("missing resource '{0}'", rc));
                                using (StreamReader sr = new StreamReader(s))
                                {
                                    while (sr.Peek() >= 0)
                                    {
                                        string line = sr.ReadLine();
                                        if (extractLoc != null)
                                            line = line.Replace("@@EXTRACTLOCATION", extractLoc);

                                        line = line.Replace("@@REMOVE_AFTER_EXECUTE", options.RemoveUnpackedFilesAfterExecute.ToString());
                                        line = line.Replace("@@QUIET", options.Quiet.ToString());
                                        if (!String.IsNullOrEmpty(options.SfxExeWindowTitle))

                                            line = line.Replace("@@SFX_EXE_WINDOW_TITLE", options.SfxExeWindowTitle);

                                        line = line.Replace("@@EXTRACT_EXISTING_FILE", ((int)options.ExtractExistingFile).ToString());

                                        if (postExCmdLine != null)
                                            line = line.Replace("@@POST_UNPACK_CMD_LINE", postExCmdLine);

                                        sb.Append(line).Append("\n");
                                    }
                                }
                                sb.Append("\n\n");
                            }
                        }
                    }

                    string LiteralSource = sb.ToString();

#if DEBUGSFX
                    // for debugging only
                    string sourceModule = GenerateTempPathname(tmpDir, "cs");
                    using (StreamWriter sw = File.CreateText(sourceModule))
                    {
                        sw.Write(LiteralSource);
                    }
                    Console.WriteLine("source: {0}", sourceModule);
#endif

                    var cr = csharp.CompileAssemblyFromSource(cp, LiteralSource);


                    if (cr == null)
                        throw new SfxGenerationException("Cannot compile the extraction logic!");

                    if (Verbose)
                        foreach (string output in cr.Output)
                            StatusMessageTextWriter.WriteLine(output);

                    if (cr.Errors.Count != 0)
                    {
                        using (TextWriter tw = new StreamWriter(sourceFile))
                        {
                            // first, the source we compiled
                            tw.Write(LiteralSource);

                            // now, append the compile errors
                            tw.Write("\n\n\n// ------------------------------------------------------------------\n");
                            tw.Write("// Errors during compilation: \n//\n");
                            string p = Path.GetFileName(sourceFile);

                            foreach (System.CodeDom.Compiler.CompilerError error in cr.Errors)
                            {
                                tw.Write(String.Format("//   {0}({1},{2}): {3} {4}: {5}\n//\n",
                                                       p,                                   // 0
                                                       error.Line,                          // 1
                                                       error.Column,                        // 2
                                                       error.IsWarning ? "Warning" : "error",   // 3
                                                       error.ErrorNumber,                   // 4
                                                       error.ErrorText));                  // 5
                            }
                        }
                        throw new SfxGenerationException(String.Format("Errors compiling the extraction logic!  {0}", sourceFile));
                    }

                    OnSaveEvent(ZipProgressEventType.Saving_AfterCompileSelfExtractor);

                    // Now, copy the resulting EXE image to the _writestream.
                    // Because this stub exe is being saved first, the effect will be to
                    // concatenate the exe and the zip data together.
                    using (System.IO.Stream input = System.IO.File.OpenRead(stubExe))
                    {
                        byte[] buffer = new byte[4000];
                        int n = 1;
                        while (n != 0)
                        {
                            n = input.Read(buffer, 0, buffer.Length);
                            if (n != 0)
                                WriteStream.Write(buffer, 0, n);
                        }
                    }
                }

                OnSaveEvent(ZipProgressEventType.Saving_AfterSaveTempArchive);
            }
            finally
            {
                try
                {
                    if (Directory.Exists(unpackedResourceDir))
                    {
                        try { Directory.Delete(unpackedResourceDir, true); }
                        catch (System.IO.IOException exc1)
                        {
                            StatusMessageTextWriter.WriteLine("Warning: Exception: {0}", exc1);
                        }
                    }
                    if (File.Exists(stubExe))
                    {
                        try { File.Delete(stubExe); }
                        catch (System.IO.IOException exc1)
                        {
                            StatusMessageTextWriter.WriteLine("Warning: Exception: {0}", exc1);
                        }
                    }
                }
                catch (System.IO.IOException) { }
            }

            return;

        }
        /// <summary>
        ///   Saves the ZipFile instance to a self-extracting zip archive, using
        ///   the specified save options.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   This method saves a self extracting archive, using the specified save
        ///   options. These options include the flavor of the SFX, the default extract
        ///   directory, the icon file, and so on.  See the documentation
        ///   for <see cref="SaveSelfExtractor(string , SelfExtractorFlavor)"/> for more
        ///   details.
        /// </para>
        ///
        /// <para>
        ///   The user who runs the SFX will have the opportunity to change the extract
        ///   directory before extracting. If at the time of extraction, the specified
        ///   directory does not exist, the SFX will create the directory before
        ///   extracting the files.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <example>
        ///   This example saves a WinForms-based self-extracting archive EXE that
        ///   will use c:\ExtractHere as the default extract location. The C# code
        ///   shows syntax for .NET 3.0, which uses an object initializer for
        ///   the SelfExtractorOptions object.
        /// <code>
        /// string DirectoryPath = "c:\\Documents\\Project7";
        /// using (ZipFile zip = new ZipFile())
        /// {
        ///     zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath));
        ///     zip.Comment = "This will be embedded into a self-extracting WinForms-based exe";
        ///     var options = new SelfExtractorOptions
        ///     {
        ///       Flavor = SelfExtractorFlavor.WinFormsApplication,
        ///       DefaultExtractDirectory = "%USERPROFILE%\\ExtractHere",
        ///       PostExtractCommandLine = ExeToRunAfterExtract,
        ///       SfxExeWindowTitle = "My Custom Window Title",
        ///       RemoveUnpackedFilesAfterExecute = true
        ///     };
        ///     zip.SaveSelfExtractor("archive.exe", options);
        /// }
        /// </code>
        /// <code lang="VB">
        /// Dim DirectoryPath As String = "c:\Documents\Project7"
        /// Using zip As New ZipFile()
        ///     zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath))
        ///     zip.Comment = "This will be embedded into a self-extracting console-based exe"
        ///     Dim options As New SelfExtractorOptions()
        ///     options.Flavor = SelfExtractorFlavor.WinFormsApplication
        ///     options.DefaultExtractDirectory = "%USERPROFILE%\\ExtractHere"
        ///     options.PostExtractCommandLine = ExeToRunAfterExtract
        ///     options.SfxExeWindowTitle = "My Custom Window Title"
        ///     options.RemoveUnpackedFilesAfterExecute = True
        ///     zip.SaveSelfExtractor("archive.exe", options)
        /// End Using
        /// </code>
        /// </example>
        ///
        /// <param name="exeToGenerate">The name of the EXE to generate.</param>
        /// <param name="options">provides the options for creating the
        /// Self-extracting archive.</param>
        public void SaveSelfExtractor(string exeToGenerate, SelfExtractorSaveOptions options)
        {
            // Save an SFX that is both an EXE and a ZIP.

            // Check for the case where we are re-saving a zip archive
            // that was originally instantiated with a stream.  In that case,
            // the _name will be null. If so, we set _writestream to null,
            // which insures that we'll cons up a new WriteStream (with a filesystem
            // file backing it) in the Save() method.
            if (_name == null)
                _writestream = null;

            _SavingSfx = true;
            _name = exeToGenerate;
            if (Directory.Exists(_name))
                throw new ZipException("Bad Directory", new System.ArgumentException("That name specifies an existing directory. Please specify a filename.", "exeToGenerate"));
            _contentsChanged = true;
            _fileAlreadyExists = File.Exists(_name);

            _SaveSfxStub(exeToGenerate, options);

            Save();
            _SavingSfx = false;
        }
        //string _defaultExtractLocation;
        //string _postExtractCmdLine;
        //         string _SetDefaultLocationCode =
        //         "namespace Ionic.Zip { public partial class WinFormsSelfExtractorStub { partial void _SetDefaultExtractLocation() {" +
        //         " txtExtractDirectory.Text = \"@@VALUE\"; } }}";



        /// <summary>
        /// Saves the ZipFile instance to a self-extracting zip archive.
        /// </summary>
        ///
        /// <remarks>
        ///
        /// <para>
        /// The generated exe image will execute on any machine that has the .NET
        /// Framework 2.0 installed on it.  The generated exe image is also a
        /// valid ZIP file, readable with DotNetZip or another Zip library or tool
        /// such as WinZip.
        /// </para>
        ///
        /// <para>
        /// There are two "flavors" of self-extracting archive.  The
        /// <c>WinFormsApplication</c> version will pop up a GUI and allow the
        /// user to select a target directory into which to extract. There's also
        /// a checkbox allowing the user to specify to overwrite existing files,
        /// and another checkbox to allow the user to request that Explorer be
        /// opened to see the extracted files after extraction.  The other flavor
        /// is <c>ConsoleApplication</c>.  A self-extractor generated with that
        /// flavor setting will run from the command line. It accepts command-line
        /// options to set the overwrite behavior, and to specify the target
        /// extraction directory.
        /// </para>
        ///
        /// <para>
        /// There are a few temporary files created during the saving to a
        /// self-extracting zip.  These files are created in the directory pointed
        /// to by <see cref="ZipFile.TempFileFolder"/>, which defaults to <see
        /// cref="System.IO.Path.GetTempPath"/>.  These temporary files are
        /// removed upon successful completion of this method.
        /// </para>
        ///
        /// <para>
        /// When a user runs the WinForms SFX, the user's personal directory (<see
        /// cref="Environment.SpecialFolder.Personal">Environment.SpecialFolder.Personal</see>)
        /// will be used as the default extract location.  If you want to set the
        /// default extract location, you should use the other overload of
        /// <c>SaveSelfExtractor()</c>/ The user who runs the SFX will have the
        /// opportunity to change the extract directory before extracting. When
        /// the user runs the Command-Line SFX, the user must explicitly specify
        /// the directory to which to extract.  The .NET Framework 2.0 is required
        /// on the computer when the self-extracting archive is run.
        /// </para>
        ///
        /// <para>
        /// NB: This method is not available in the version of DotNetZip build for
        /// the .NET Compact Framework, nor in the "Reduced" DotNetZip library.
        /// </para>
        ///
        /// </remarks>
        ///
        /// <example>
        /// <code>
        /// string DirectoryPath = "c:\\Documents\\Project7";
        /// using (ZipFile zip = new ZipFile())
        /// {
        ///     zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath));
        ///     zip.Comment = "This will be embedded into a self-extracting console-based exe";
        ///     zip.SaveSelfExtractor("archive.exe", SelfExtractorFlavor.ConsoleApplication);
        /// }
        /// </code>
        /// <code lang="VB">
        /// Dim DirectoryPath As String = "c:\Documents\Project7"
        /// Using zip As New ZipFile()
        ///     zip.AddDirectory(DirectoryPath, System.IO.Path.GetFileName(DirectoryPath))
        ///     zip.Comment = "This will be embedded into a self-extracting console-based exe"
        ///     zip.SaveSelfExtractor("archive.exe", SelfExtractorFlavor.ConsoleApplication)
        /// End Using
        /// </code>
        /// </example>
        ///
        /// <param name="exeToGenerate">
        ///   a pathname, possibly fully qualified, to be created. Typically it
        ///   will end in an .exe extension.</param>
        /// <param name="flavor">
        ///   Indicates whether a Winforms or Console self-extractor is
        ///   desired. </param>
        public void SaveSelfExtractor(string exeToGenerate, SelfExtractorFlavor flavor)
        {
            SelfExtractorSaveOptions options = new SelfExtractorSaveOptions();
            options.Flavor = flavor;
            SaveSelfExtractor(exeToGenerate, 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 );
            }
        }
Exemple #12
0
        private bool ZipFiles()
        {
            try
            {
                Log.LogMessage(Resources.ZipCreating, ZipFileName);

                string directoryName = Path.GetDirectoryName(Path.GetFullPath(ZipFileName));
                if (!Directory.Exists(directoryName))
                    Directory.CreateDirectory(directoryName);

                using (var zip = new ZipFile())
                {
                    if (!ParallelCompression)
                    {
                        zip.ParallelDeflateThreshold = -1;
                    }

                    zip.AlternateEncoding = System.Text.Encoding.Unicode;
                    zip.AlternateEncodingUsage = ZipOption.AsNecessary;

                    // make sure level in range
                    ZipLevel = System.Math.Max(0, ZipLevel);
                    ZipLevel = System.Math.Min(9, ZipLevel);
                    zip.CompressionLevel = (CompressionLevel)ZipLevel;

                    zip.UseZip64WhenSaving = Zip64 ? Zip64Option.AsNecessary: Zip64Option.Never;

                    if (!string.IsNullOrEmpty(Password))
                        zip.Password = Password;

                    if (string.Equals(Encryption, "PkzipWeak", StringComparison.OrdinalIgnoreCase))
                        zip.Encryption = EncryptionAlgorithm.PkzipWeak;
                    else if (string.Equals(Encryption, "WinZipAes128", StringComparison.OrdinalIgnoreCase))
                        zip.Encryption = EncryptionAlgorithm.WinZipAes128;
                    else if (string.Equals(Encryption, "WinZipAes256", StringComparison.OrdinalIgnoreCase))
                        zip.Encryption = EncryptionAlgorithm.WinZipAes256;
                    else
                        zip.Encryption = EncryptionAlgorithm.None;

                    if (!string.IsNullOrEmpty(Comment))
                        zip.Comment = Comment;

                    foreach (ITaskItem fileItem in Files)
                    {
                        string name = fileItem.ItemSpec;
                        string directoryPathInArchive;

                        // clean up name
                        if (Flatten)
                            directoryPathInArchive = string.Empty;
                        else if (!string.IsNullOrEmpty(WorkingDirectory))
                            directoryPathInArchive = GetPath(name, WorkingDirectory);
                        else
                            directoryPathInArchive = null;

                        if (!File.Exists(name))
                        {
                            // maybe a directory
                            if (Directory.Exists(name))
                            {
                                var directoryEntry = zip.AddDirectory(name, directoryPathInArchive);
                                if (!Quiet)
                                    Log.LogMessage(Resources.ZipAdded, directoryEntry.FileName);

                                continue;
                            }

                            Log.LogWarning(Resources.FileNotFound, name);
                            continue;
                        }

                        //remove file name
                        if (!string.IsNullOrEmpty(directoryPathInArchive)
                            && Path.GetFileName(directoryPathInArchive) == Path.GetFileName(name))
                            directoryPathInArchive = Path.GetDirectoryName(directoryPathInArchive);

                        var entry = zip.AddFile(name, directoryPathInArchive);
                        if (!Quiet)
                            Log.LogMessage(Resources.ZipAdded, entry.FileName);
                    }

                    if (SelfExtracting)
                    {
                        var options = new SelfExtractorSaveOptions
                        {
                            AdditionalCompilerSwitches = AdditionalCompilerSwitches,
                            Copyright = Copyright,
                            DefaultExtractDirectory = DefaultExtractDirectory,
                            Description = Description,
                            ExtractExistingFile = (ExtractExistingFileAction) ExtractExistingFileAction,
                            Flavor = ConsoleSelfExtractor
                                    ? SelfExtractorFlavor.ConsoleApplication
                                    : SelfExtractorFlavor.WinFormsApplication,
                            IconFile = IconFile,
                            PostExtractCommandLine = PostExtractCommandLine,
                            ProductName = ProductName,
                            ProductVersion = ProductVersion,
                            Quiet = QuietExtraction,
                            RemoveUnpackedFilesAfterExecute = RemoveUnpackedFilesAfterExecute,
                            SfxExeWindowTitle = SelfExtractingArchiveWindowTitle
                        };

                        if (!string.IsNullOrWhiteSpace(FileVersion))
                        {
                            options.FileVersion = new System.Version(FileVersion);
                        }

                        zip.SaveSelfExtractor(ZipFileName, options);
                    }
                    else
                    {
                        zip.Save(ZipFileName);
                    }

                    Log.LogMessage(Resources.ZipSuccessfully, ZipFileName);
                }
            }
            catch (Exception exc)
            {
                Log.LogErrorFromException(exc);
                return false;
            }

            return true;
        }
Exemple #13
0
        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);
                    }
                }
            }
        }
Exemple #14
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);
                }
            }
        }
Exemple #15
0
        public void SFX_WinForms()
        {
            string[] Passwords = { null, "12345" };
            for (int k = 0; k < Passwords.Length; k++)
            {
                string exeFileToCreate = Path.Combine(TopLevelDir, String.Format("SFX_WinForms-{0}.exe", k));
                string DesiredunpackDir = 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:  " + DesiredunpackDir;
                    if (Passwords[k] != null) zip.Comment += String.Format("\r\n\r\nThe password for all entries is:  {0}\n", Passwords[k]);
                    var sfxOptions = new SelfExtractorSaveOptions
                    {
                        Flavor = Ionic.Zip.SelfExtractorFlavor.WinFormsApplication,
                        // workitem 12608
                        SfxExeWindowTitle = "Custom SFX Title " + DateTime.Now.ToString("G"),
                        DefaultExtractDirectory = DesiredunpackDir
                    };
                    zip.SaveSelfExtractor(exeFileToCreate, sfxOptions);
                }

                // run the self-extracting EXE we just created
                System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(exeFileToCreate);
                psi.Arguments = DesiredunpackDir;
                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(DesiredunpackDir, 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);
                }
            }
        }
Exemple #16
0
        public void SFX_Console()
        {
            string exeFileToCreate = Path.Combine(TopLevelDir, "SFX_Console.exe");
            string unpackDir = 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);
                var sfxOptions = new SelfExtractorSaveOptions
                {
                    Flavor = Ionic.Zip.SelfExtractorFlavor.ConsoleApplication,
                    DefaultExtractDirectory = unpackDir
                };
                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 unpackDir with the original
            string DirToCheck = Path.Combine(unpackDir, "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);

            }
        }
Exemple #17
0
        private void SFX_Update(SelfExtractorFlavor flavor)
        {
            string sfxFileToCreate = Path.Combine(TopLevelDir,
                                                  String.Format("SFX_Update{0}.exe",
                                                                flavor.ToString()));
            string unpackDir = Path.Combine(TopLevelDir, "unpack");
            if (Directory.Exists(unpackDir))
                Directory.Delete(unpackDir, 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);
                var sfxOptions = new SelfExtractorSaveOptions
                {
                    Flavor = flavor,
                    Quiet = true,
                    DefaultExtractDirectory = unpackDir
                };
                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));
                var sfxOptions = new SelfExtractorSaveOptions
                {
                    Flavor = flavor,
                    Quiet = true,
                    DefaultExtractDirectory = unpackDir
                };
                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(unpackDir);
                    if (!e.IsDirectory)
                    {
                        if (checksums.ContainsKey(e.FileName))
                        {
                            filename = Path.Combine(unpackDir, 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?
        }