SelfExtractor.cs :  » Development » DotNetZip » Ionic » Zip » Tests » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Development » DotNetZip 
DotNetZip » Ionic » Zip » Tests » SelfExtractor.cs
// SelfExtractor.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.  
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License. 
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// last saved (in emacs): 
// Time-stamp: <2009-October-15 11:59:00>
//
// ------------------------------------------------------------------
//
// This module defines the tests for the self-extracting archive capability
// within DotNetZip: creating, reading, updating, and running SFX's. 
//
// ------------------------------------------------------------------


using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using Ionic.Zip;
using Ionic.Zip.Tests.Utilities;
using System.IO;


namespace Ionic.Zip.Tests{
    /// <summary>
    /// Summary description for Self extracting archives (SFX)
    /// </summary>
    [TestClass]
    public class SelfExtractor : IonicTestClass
    {
        public SelfExtractor() : base() { }


        [TestMethod]
        public void SelfExtractor_CanRead()
        {
            SelfExtractorFlavor[] flavors =
            {
                SelfExtractorFlavor.ConsoleApplication,
                SelfExtractorFlavor.WinFormsApplication
            };
        
            for (int k = 0; k < flavors.Length; k++)
            {
                string SfxFileToCreate = Path.Combine(TopLevelDir, String.Format("SelfExtractor_{0}.exe", flavors[k].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.";

                int entriesAdded = 0;
                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(50) + 30;
                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.Replace(TopLevelDir + "\\", "").Replace('\\', '/'), TestUtilities.CheckSumToString(chk));
                }

                using (ZipFile zip1 = new ZipFile())
                {
                    zip1.AddDirectory(Subdir, 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);
                    zip1.SaveSelfExtractor(SfxFileToCreate, flavors[k]);
                }

                TestContext.WriteLine("---------------Reading {0}...", SfxFileToCreate);
                using (ZipFile zip2 = ZipFile.Read(SfxFileToCreate))
                {
                    //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, "In trial {0}, Checksums for ({1}) do not match.", k, e.FileName);
                            }
                            else
                            {
                                Assert.AreEqual<string>("Readme.txt", e.FileName, String.Format("trial {0}", k));
                            }
                        }
                    }
                }
            }
        }



        [TestMethod]
        public void SelfExtractor_Update_Console()
        {
            SelfExtractor_Update(SelfExtractorFlavor.ConsoleApplication);
        }

        [TestMethod]
        public void SelfExtractor_Update_Winforms()
        {
            SelfExtractor_Update(SelfExtractorFlavor.WinFormsApplication);
        }

        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 = "ABCDEFG"; 
            // 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?
        }



        [TestMethod]
        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);

            }
        }


        [TestMethod]
        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);
                }
            }
        }



        string programCode =

            "using System;\n" +
            "namespace Ionic.Tests.Zip.SelfExtractor\n" +
            "{\n" +
            "\n" +
            "    public class TestDriver\n" +
            "    {\n" +
            "        static int Main(String[] args)\n" +
            "        {\n" +
            "            int rc = @@XXX@@;\n" +
            "            Console.WriteLine(\"Hello from the post-extract command.\\nThis app will return {0}.\", rc);\n" +
            "            return rc;\n" +
            "        }\n" +
            "    }\n" +
            "}\n";


        private void CompileApp(int rc, string pathToExe)
        {
            Microsoft.CSharp.CSharpCodeProvider csharp = new Microsoft.CSharp.CSharpCodeProvider();

            //System.CodeDom.Compiler.ICodeCompiler csharpCompiler = csharp.CreateCompiler();

            var cp = new System.CodeDom.Compiler.CompilerParameters();
            cp.GenerateInMemory = false;
            cp.GenerateExecutable = true;
            cp.IncludeDebugInformation = false;
            cp.OutputAssembly = pathToExe;

            // set the return code in the app
            var cr = csharp.CompileAssemblyFromSource(cp, programCode.Replace("@@XXX@@", rc.ToString()));
            if (cr == null)
                throw new Exception("Errors compiling!");

            foreach (string s in cr.Output)
                TestContext.WriteLine(s);

            if (cr.Errors.Count != 0)
                throw new Exception("Errors compiling!");
        }


        // Here's a set of SFX tests with post-extract EXEs. 
        // We vary these parameters:
        //  - exe exists or not - 2 trials each test. 
        //  - exe name has spaces or not
        //  - winforms or not
        //  - whether to run the exe or just compile
        //  - whether to append args or not
        //  - force noninteractive or not (only for Winforms flavor, to allow automated tests)

        [TestMethod]
        public void SelfExtractor_RunOnExit_Console()
        {
            _Internal_SelfExtractor_Command("post-extract-run-on-exit-{0:D4}.exe",
                                            SelfExtractorFlavor.ConsoleApplication,
                                            true,   // runPostExtract
                                            true,   // quiet
                                            false,  // forceNoninteractive
                                            false); // wantArgs
        }

        [TestMethod]
        public void SelfExtractor_RunOnExit_Console_Args()
        {
            _Internal_SelfExtractor_Command("post-extract-run-on-exit-{0:D4}.exe",
                                            SelfExtractorFlavor.ConsoleApplication,
                                            true,   // runPostExtract
                                            true,   // quiet
                                            false,  // forceNoninteractive
                                            true); // wantArgs
        }

        [TestMethod]
        public void SelfExtractor_RunOnExit_WinForms()
        {
            _Internal_SelfExtractor_Command("post-extract-run-on-exit-{0:D4}.exe",
                                            SelfExtractorFlavor.WinFormsApplication,
                                            true,   // runPostExtract
                                            true,   // quiet
                                            false,  // forceNoninteractive
                                            false); // wantArgs
        }

        [TestMethod]
        public void SelfExtractor_RunOnExit_WinForms_DontRun()
        {
            // This test case just tests the generation (compilation) of
            // the SFX.  It is included because the interactive winforms
            // SFX is not performed on automated test runs.
            _Internal_SelfExtractor_Command("post-extract-run-on-exit-{0:D4}.exe",
                                            SelfExtractorFlavor.WinFormsApplication,
                                            false,  // runPostExtract
                                            true,   // quiet
                                            false,  // forceNoninteractive
                                            false); // wantArgs
        }

        [TestMethod]
        public void SelfExtractor_RunOnExit_WinForms_Interactive()
        {
            _Internal_SelfExtractor_Command("post-extract-run-on-exit-{0:D4}.exe",
                                            SelfExtractorFlavor.WinFormsApplication,
                                            true,   // runPostExtract
                                            false,  // quiet
                                            false,  // forceNoninteractive
                                            false); // wantArgs
        }

        [TestMethod]
        public void SelfExtractor_RunOnExit_WinForms_NonInteractive()
        {
            _Internal_SelfExtractor_Command("post-extract-run-on-exit-{0:D4}.exe",
                                            SelfExtractorFlavor.WinFormsApplication,
                                            true,   // runPostExtract
                                            true,   // quiet
                                            true,   // forceNoninteractive
                                            false); // wantArgs
        }

        [TestMethod]
        public void SelfExtractor_RunOnExit_WinForms_NonInteractive_Args()
        {
            _Internal_SelfExtractor_Command("post-extract-run-on-exit-{0:D4}.exe",
                                            SelfExtractorFlavor.WinFormsApplication,
                                            true,   // runPostExtract
                                            true,   // quiet
                                            true,   // forceNoninteractive
                                            true); // wantArgs
        }

        // ------------------------------------------------------------------ //
        
        [TestMethod]
        public void SelfExtractor_RunOnExit_Console_withSpaces()
        {
            _Internal_SelfExtractor_Command("post extract run on exit {0:D4}.exe",
                                            SelfExtractorFlavor.ConsoleApplication,
                                            true,   // runPostExtract
                                            true,   // quiet
                                            false,  // forceNoninteractive
                                            false); // wantArgs
        }

        
        [TestMethod]
        public void SelfExtractor_RunOnExit_Console_withSpaces_Args()
        {
            _Internal_SelfExtractor_Command("post extract run on exit {0:D4}.exe",
                                            SelfExtractorFlavor.ConsoleApplication,
                                            true,   // runPostExtract
                                            true,   // quiet
                                            false,  // forceNoninteractive
                                            true);  // wantArgs
        }
        
        [TestMethod]
        public void SelfExtractor_RunOnExit_WinForms_withSpaces()
        {
            _Internal_SelfExtractor_Command("post extract run on exit {0:D4}.exe",
                                            SelfExtractorFlavor.WinFormsApplication,
                                            true,   // runPostExtract
                                            true,   // quiet
                                            false,  // forceNoninteractive
                                            false); // wantArgs
        }

        [TestMethod]
        public void SelfExtractor_RunOnExit_WinForms_withSpaces_DontRun()
        {
            // This test case just tests the generation (compilation) of
            // the SFX.  It is included because the interactive winforms
            // SFX is not performed on automated test runs.
            _Internal_SelfExtractor_Command("post extract run on exit {0:D4}.exe",
                                            SelfExtractorFlavor.WinFormsApplication,
                                            false,  // runPostExtract
                                            true,   // quiet
                                            false,  // forceNoninteractive
                                            false); // wantArgs
        }
        
        [TestMethod]
        public void SelfExtractor_RunOnExit_WinForms_withSpaces_Interactive()
        {
            _Internal_SelfExtractor_Command("post extract run on exit {0:D4}.exe",
                                            SelfExtractorFlavor.WinFormsApplication,
                                            true,   // actually run the program
                                            false,  // quiet
                                            false,  // forceNoninteractive
                                            false); // wantArgs
        }

        [TestMethod]
        public void SelfExtractor_RunOnExit_WinForms_withSpaces_NonInteractive()
        {
            _Internal_SelfExtractor_Command("post extract run on exit {0:D4}.exe",
                                            SelfExtractorFlavor.WinFormsApplication,
                                            true,   // actually run the program
                                            true,   // quiet
                                            true,   // forceNoninteractive
                                            false); // wantArgs
        }

        [TestMethod]
        public void SelfExtractor_RunOnExit_WinForms_withSpaces_NonInteractive_Args()
        {
            _Internal_SelfExtractor_Command("post extract run on exit {0:D4}.exe",
                                            SelfExtractorFlavor.WinFormsApplication,
                                            true,   // actually run the program
                                            true,   // quiet
                                            true,   // forceNoninteractive
                                            true); // wantArgs
        }

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

        

        [TestMethod]
        [ExpectedException(typeof(Ionic.Zip.BadStateException))]
        public void SelfExtractor_Save_Zip_As_EXE()
        {
            string SfxFileToCreate = Path.Combine(TopLevelDir, "SelfExtractor_Save_Zip_As_EXE.exe");
            
            Directory.SetCurrentDirectory(TopLevelDir);

            // create a file to zip
            string Subdir = Path.Combine(TopLevelDir, "files");
            Directory.CreateDirectory(Subdir);
            string filename = Path.Combine(Subdir, "file1.txt");
            TestUtilities.CreateAndFillFileText(filename, _rnd.Next(34000) + 5000);

            // add an entry to the zipfile, then try saving to a directory. this should fail
            using (ZipFile zip = new ZipFile())
            {
                zip.AddFile(filename, "");
                zip.SaveSelfExtractor(SfxFileToCreate, SelfExtractorFlavor.ConsoleApplication);
            }

            // create another file
            filename = Path.Combine(Subdir, "file2.txt");
            TestUtilities.CreateAndFillFileText(filename, _rnd.Next(34000) + 5000);

            // update the SFX, save to a zip format
            using (ZipFile zip = new ZipFile(SfxFileToCreate))
            {
                zip.AddFile(filename, "");
                zip.Save();  // FAIL
            }

        }
        
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.