Self Extracting EXE

Sep 30, 2009 at 3:50 PM

Is it possible to build a self extracting archive that will silently unpack to the user's profile, run a specified executable from the archive and then tidy up once the operation is completed?

 

Coordinator
Sep 30, 2009 at 5:36 PM

Self-extracting archives have a default extract location, but there is currently no "variable substitution" that would support "the current user's profile".   Sounds like a good feature to add though: do environment variable substitutions on the extract location.

There is also a execute-on-extract setting, which you can use to run a specified executable.  I don't know what you mean by "tidy up" but I suppose the executable that runs could do any tidying you need.

 

 

Coordinator
Sep 30, 2009 at 5:37 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Oct 6, 2009 at 7:36 AM

Hi,

This discussion has been moved to work item that I'm not sure addresses the main problem i am facing. If you've got a moment I'll describe in detail what I am trying to achieve.

I have an application which upgrades our main product's database. There are literally thousands of scripts used in the upgrade process. The application expects to find the scripts in a folder next to the exe.

I don't want to have to ship a zip file and get clients to unzip it somewhere then start the application. I would like to just ship an exe that unpacks the application and scripts somewhere (user profile?) then starts the application. Once the application has completed it would be nice if the unzipped files were deleted leaving just the self extracting archive.

Does this make sense? At the minute the two flavors of self exctracting archive don't quite achieve what i am after.

Coordinator
Oct 6, 2009 at 3:24 PM

OK, I think I understand what you wrote.

Why does the self-extracting archive not achieve what you are after?  Are you saying, you cannot easily run an application that was inside the SFX?   I think you're right about that but I want to be sure.

There is a "run exe on extraction" option.  You are using the SaveSelfExtractor() method that accepts a postExtractCommandToExecute argument, right?

I looked in the code and found that the Command Line self-extractor sets the working directory to the extraction directory, before executing the "post execute command".  So you can execute an exe that was inside the zip.  The WinForms self-extractor does not set the working directory, so you cannot easily execute a command that is inside the zip.  This seems like a bug in the WinForms SFX, but I Want to be sure this is the problem you are facing.

Oct 6, 2009 at 3:48 PM

Hi Cheeso,

Thanks for responding. I have tried using the SaveSelfExtractor method using the Command Line flavor and it is almost what I'm after. The problems being

  1. there is a command prompt window hanging around that looks a bit weird
  2. the files are unzipped to the location of the self extracting archive, if this was the desktop it would be a bit of a mess with my thousand odd scripts! it would be good if you could specify user profile or temp folder.
  3. once the main application has completed i would like the stub to tidy up all the files it has unzipped so that just the sfx remains.

Happy to help in whatever way i can, but i'm more of a vb/sql guy than c# unfortunately.

Cheers,

Ste

Coordinator
Oct 6, 2009 at 4:56 PM

Hm, ok.

  1. I guess you are starting the exe by double-click?  The CMD window won't be there if you use the WinForms GUI SFX, once I get that bug fixed (the one I mentioned above about setting the working directory).  This will be in just a few minutes.
  2. The files can be unzipped to a specific directory - with either the command line SFX or the Winforms GUI SFX.  In the command line version you need to pass an argument to the exe to specify which directory to extract to.  Obviously you can't do this, if the way you run the sfx exe is to double-click it in Explorer.  in the WinForms SFX you specify the extract directory with a textbox.
  3. You want dotnetzip to delete all the files it has unpacked, after the "post extract exe" completes.   Is that right?   I'll have to look into this. 
    My original thought was, that doesn't seem the right way to do things.  Why should a "Self extractor" delete the files it extracted?   Seems to me the "post extract exe" - your exe - should be responsible for that kind of thing.  But I can see the utility in having the SFX do the cleanup.  And it wouldn't be that hard to add to DotNetZip.  I have to think about this a little more. 

 

Coordinator
Oct 6, 2009 at 5:03 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Oct 6, 2009 at 5:58 PM

Hi,

Here's a little extra background to explain the reasoning behind my ideas

I have written an application to upgrade our clients database. The finished app consists of an exe, a few dlls and a few hundred scripts. The scripts are built as part of a seperate process and so will be different from build to build, the exe and dlls are expected to remain static.

I need to ship the lot to our clients in a format that gives them the minimum opportunity to get things wrong! I could zip the lot up and tell them to extract it somewhere then run the exe - but this will undoubtably be too hard for some of them (really!!) What i would like to ship is one file that you double click and it opens the application with the files ready to go. I suppose i could somehow add the scripts as resources and embed them into the exe somehow, but what about the dlls? Another option would be to use an msi file, but we aren't really installing anything on the machine in terms of a client app so this seems wrong - plus I hate trying to build msi files!

What I'm after is one file, an exe that users can just double click and my application starts up - as if it was the exe they just clicked on. Once the application has finished the self extracting stub tidies up the files it unipped so to the users eyes the unzipping is invisible - they just ran a plain old exe.

 

 

Coordinator
Oct 6, 2009 at 7:53 PM

That's helpful.

 

Coordinator
Oct 7, 2009 at 3:59 AM

ok, I just posted v1.9.0.15 that includes changes for you.

The programming model for SaveSelfExtractor has changed to support the extra stuff you asked for, including removing of files after the post-extract command executes.  Here's an example:

    // create the SFX
    using (ZipFile zip1 = new ZipFile())
    {
        zip1.AddFiles(files, "");
        zip1.AddFile(postExtractExe, "");
        zip1.Comment = "This will be embedded into a self-extracting exe";
        zip1.AddEntry("Readme.txt", "This is the content for the readme file...");
        SelfExtractorSaveOptions sfxOptions = new SelfExtractorSaveOptions();
        sfxOptions.Flavor = SelfExtractorFlavor.ConsoleApplication;
        sfxOptions.Quiet = true; // hides the window after startup
        sfxOptions.DefaultExtractDirectory = "%USERPROFILE%\\AppData\\Local\\Temp\\patch1";
        sfxOptions.PostExtractCommandLine= postExtractExe;
        sfxOptions.RemoveUnpackedFilesAfterExecute = true; 
        zip1.SaveSelfExtractor(SfxFileToCreate, sfxOptions);
    }

I learned that there's no way to make an EXE that can sometimes emit messages to the console, and sometimes not. So, the ConsoleApplication SFX, when you double-click it in explorer or as an attachment, will hide the window that Windows gives it, if the Quiet flag is set. You see the window appear and then it disappears.  If you run the ConsoleApplication SFX from the cmd.exe prompt, it runs as a normal console app, and displays messages to the console.

If you don't set the Quiet flag, then when double-clicking to launch the SFX, the window will remain, and the SFX will emit a message for each file as it extracts. The messages fly by so quickly, they won't be easily readable.  But now you have a choice - either a window that pops up and disappears, or a window that stays up and displays messages. I think either is preferable to a empty window that never displays anything, which is what it was before. 

You also now have environment variable expansion.  The syntax is like %USERPROFILE%, and the env vars get expanded when the SFX is run.  You can use them in either the DefaultExtractDirectory or in the PostExtractCommandLine.  If the env var is unknown at runtime, the string remains - it does not evaluate to (blank). 

RemoveUnpackedFilesAfterExecute works only if you have a non-empty PostExtractCommandLine.  It causes the SFX to wait until the command specified in PostExtractCommandLine completes, and then removes all the unpacked files. Then the SFX exits.  If the PostExtractCommandLine returns a non-zero status code, that is taken as a failure, and the SFX does not remove the unpacked files in that case. 

This is all documented in the CHM file.

Let me know if this works for you.

Oct 7, 2009 at 8:13 AM

Hi Cheeso,

That's great, thanks! I've had another idea if you have the time...

Rather than have a console app stub which flicks up a command window, would it be possible to just have a progress bar showing the unzip progress and maye some text along the lines of "Preparing application..."? The unzip process could take a while given the large amount of files, so a progress bar would stop the users opening the sfx again (...and again, and again!!)

Appreciate your time on this.

Coordinator
Oct 7, 2009 at 4:20 PM

Hey Ste, that isn't what you asked for last time!

Ok, I posted v1.9.0.16.  If you set the Quiet flag and use a WinForms flavor, then it will show a progress bar as it runs, which I think is what you described.  You also may want to set the PostExtractCommandLine and RemoveUnpackedFilesAfterExecute.

Try it and let me know.

Oct 8, 2009 at 12:59 AM

Hey, I'd love a copy of this build.  Where do I go to download it?

 

thanks,

 

David

 

Oct 8, 2009 at 1:00 AM

Sorry, posting a spam so I can check the box to get an email when you reply.

Coordinator
Oct 8, 2009 at 6:37 AM
Edited Oct 8, 2009 at 6:41 AM

on http://dotnetzip.codeplex.com/Release/ProjectReleases.aspx

The default release is v1.8.  You don't want that.  You want the v1.9 release.  Look in the far-right side, near the top, you'll see a box with release options.

 

Oct 14, 2009 at 2:21 PM

Hi Cheeso,

Sorry for the delay in responding on this, I've had other more mundane tasks to attend to :o(

Anyhoo I have decided to write my own self extracting stub rather than keep pestering you for minor changes and i am nearly done :o) My only problem is creating the SFX. I write out my EXE to a stream and append the zip file using the following code but I end up with a corrupt archive. Could you point me in the right direction? Many thanks, ste

	Using zp As New ZipFile
            zp.AddFiles(Directory.GetFiles("P:\PS ProSolution\System\Devel\Setup\New Installer\Patch\Wizard"), False, "")

            Dim asm As Reflection.Assembly = Reflection.Assembly.GetAssembly(GetType(SFXStub.Form1))
            Dim output As New FileStream("C:\steeee.exe", FileMode.Create)

            Using input As System.IO.Stream = asm.GetFiles()(0)
                Dim buffer As Byte() = New Byte(3999) {}
                Dim n As Integer = 1
                While n <> 0
                    n = input.Read(buffer, 0, buffer.Length)
                    If n <> 0 Then
                        output.Write(buffer, 0, n)
                    End If
                End While
            End Using

            zp.Save("c:\test.zip")

            Using input As System.IO.Stream = New FileStream("c:\test.zip", FileMode.Open)
                Dim buffer As Byte() = New Byte(3999) {}
                Dim n As Integer = 1
                While n <> 0
                    n = input.Read(buffer, 0, buffer.Length)
                    If n <> 0 Then
                        output.Write(buffer, 0, n)
                    End If
                End While
            End Using

            output.Close()

            'My.Application.Info.LoadedAssemblies
        End Using
Coordinator
Oct 14, 2009 at 6:19 PM
Edited Oct 14, 2009 at 6:23 PM

Writing your own extractor stub - well good for you.  Sounds like a good project.

In my opinion there are two ways to go, if you want a self-extracting archive.  First is to embed the zip as an "embedded resource".  The second is to append the zip content after the EXE "stub" content. 

If you go the first route, you can just read the zip from the resource Stream that you get from Assembly.GetManifestResourceStream().  This works just fine.  The resulting exe file is not readable as a regular zip file though.  You cannot examine it in WinZip, or using DotNetZip.  The file is an EXE file, with an embedded zip file.

With option 2, the generated EXE will be both a zip and an EXE.  There's just one tricky part: you have to take care to deal with the issue of offsets. Within the zip file there are offsets that refer to points in the zip stream where entries are found.  Let's suppose you have a zipfile of 1000 bytes.  The zip directory falls at the end of the file, say, the last 100 bytes.  In there are values that point to positions in the prior 900 bytes, at which zip entry data is found.  An offset of 0 for entry #0 in that directory will refer to the first byte in the zip stream, byte 0 of 1000.  An offset of 100 for entry #1 will refer to byte 100 of 1000.

Now suppose you append that zip file, with the offsets unchanged onto an exe stub.  Suppose the exe stub is 10,000 bytes long.  The total file size is thus 11,000 bytes - 10,000 for the exe stub, and 1000 for the appended zip content.  An offset of 0 in the zip directory, which previously refered to byte 0 of 1000, now refers to byte 0 of 11,000 in the file.  If you try to read a zip entry at byte 0, you will get rubbish.  You will be trying to read a zipentry where the PE-COFF (EXE) header is found .  That won't work.

This is what you are seeing.  you are appending a zip datastream without modification to the end of your stubexe content.

So you need to adjust the offsets.

One way to do it would be to adjust every offset in the zip datastream, after it has been written, to refer to the adjusted position in the file.  An offset of 0 must change to an offset of 10,000.  An offset of 100 must change to an offset of 10,100.  And so on.  You would need to modify each offset in the stream.  This is tedious and requires re-parsing the generated zip datastream.  I don't recommend it.

There's another way - DotNetZip is smart enough when writing zip content out to a stream to use the Stream.Position value to determine the offset.  So, when generating the SFX, if you do this:

  • create and open a stream
  • write the sfx stub out to the stream
  • write the zip content out to the same stream
  • close that single stream

...then the offsets in the zip content will be correct.

in code, you would need to replace this code in your example:

            zp.Save("c:\test.zip")

            Using input As System.IO.Stream = New FileStream("c:\test.zip", FileMode.Open)
                Dim buffer As Byte() = New Byte(3999) {}
                Dim n As Integer = 1
                While n <> 0
                    n = input.Read(buffer, 0, buffer.Length)
                    If n <> 0 Then
                        output.Write(buffer, 0, n)
                    End If
                End While
            End Using

            output.Close()

with the much simpler

     zp.Save(output)

it looks like this:

    Using zp As New ZipFile
        zp.AddFiles(Directory.GetFiles("P:\PS ProSolution\System\Devel\Setup\New Installer\Patch\Wizard"), False, "")

        Dim asm As Reflection.Assembly = Reflection.Assembly.GetAssembly(GetType(SFXStub.Form1))
        Using output As As System.IO.Stream = New FileStream("C:\steeee.exe", FileMode.Create)

            Using input As System.IO.Stream = asm.GetFiles()(0)
                Dim buffer As Byte() = New Byte(3999) {}
                Dim n As Integer = 1
                While n <> 0
                    n = input.Read(buffer, 0, buffer.Length)
                    If n <> 0 Then
                        output.Write(buffer, 0, n)
                    End If
                End While
            End Using

            zp.Save(output)
        End Using

    End Using

(You should be using a Using clause for the output stream.)   Then, for extraction, the EXE in outputFile (in your stub) must do a ZipFile.Read() using itself as the input.   It must read the file location of the currently executing EXE.

Something like this:

Assembly a = Assembly.GetExecutingAssembly();
try
{
    using (ZipFile zip = ZipFile.Read(a.Location))
    {
        foreach (ZipEntry entry in zip)
        {
            // handle each entry here
        }
    }
}
...

I know you're a VB guy, but I figure you can see what's going on there. 

Also I can see you're no stranger to Reflector. Generate an SFX with DotNetZip in the traditional way and then examine the result in Reflector to see what I mean.

I don't know exactly what you're doing with Using input As System.IO.Stream = asm.GetFiles()(0)
I think that gets the first file in the list of files for the given assembly.  If that just opens the stub exe, then it seems right to me.

 

Oct 14, 2009 at 11:24 PM

Hi Cheeso,

That's great, it's quite difficult to find this info anywhere on the internet.

However, I initially tried the method you mention above and something goes wrong as i end up with an exe that is seen as a console app and runs with error "Program too big to fit in memory". It behaves well as a zip but not an exe, any ideas.

Really appreciate your help on this.

Ste

Coordinator
Oct 15, 2009 at 12:44 AM

> an exe that is seen as a console app

Hmm, I don't know what that means. If I were you, to troubleshoot it I would produce a super small basic EXE, just a basic form with a "Close" button.  (It shouldn't try to do anything with the appended zip file).   Then, in a separate app, run the code above which saves the EXE and the zip file to the same stream.  The result should be able to run as an EXE, which still just shows a "Close" button.  It should also be readable as a zip file in any tool.

If that works, then you can add one piece at a time to the app, iteratively, until you get it working the way you want.

 

Coordinator
Oct 15, 2009 at 4:16 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Coordinator
Oct 15, 2009 at 4:32 AM
Edited Oct 15, 2009 at 5:16 AM

Ste,

I took my the advice I gave you, and built an app like I described.  Surprise!  I found that it didn't work.  Turns out I was wrong when I wrote "DotNetZip is smart enough when writing zip content out to a stream to use the Stream.Position value to determine the offset."   It was almost doing that properly.   I had to modify the library to make it do the right thing.

Now that I fixed the library, it's working.  Here's how I did it.  You've got a winforms app, a "stub" self extractor, right?  And as I told you, creating the actual SFX is not just a matter of simple concatenation of the bytestreams.  You need some simple logic to create the SFX.  Here is what I used:

<STAThread> _
Public Shared Function Main(ByVal args As String()) As Integer
    Dim outputFile As String = "stee-sfx.exe"
    Dim sfxStub As String = "Stee.exe"
    Dim directoryToZip As String = "c:\directory\to\ZIP"
    Dim buffer As Byte() = New Byte(4000){}
    Dim n As Integer = 1
    Using output As System.IO.Stream = File.Open(outputFile, FileMode.Create)
        Using zp As New ZipFile
            zp.AddFiles(Directory.GetFiles(directoryToZip), False, "")
            Using input As System.IO.Stream = File.Open(sfxStub, FileMode.Open)
                While n <> 0
                    n = input.Read(buffer, 0, buffer.Length)
                    If n <> 0 Then
                        output.Write(buffer, 0, n)
                    End If
                End While
            End Using
            zp.Save(output)
        End Using
    End Using
End Function

Ok, then in the SFX stub application, you need to have the application read itself.  Here's what I used:  

Private Sub Form_Shown(ByVal sender As Object, ByVal e As EventArgs)
    Dim a As Assembly = Assembly.GetExecutingAssembly
    Try
        Using zp As ZipFile = ZipFile.Read(a.Location)
            Dim entry As ZipEntry
            For Each entry in zp
                listBox1.Items.Add(entry.FileName)
            Next
        End Using
    Catch
        listBox1.Items.Add("-No embedded zip file.-")
    End Try
End Sub

This is part of a simple WinForms app. That method is attached to the "Shown" event on the form. It reads the EXE that is currently executing, and then displays the zip entries in the listbox on the form.  You'd have to modify that logic to do something more interesting, like extract, but the basic bones are there.

To do this you need the change I made in the library.  It is available in v1.9.0.21.

 

Oct 15, 2009 at 7:53 AM

Hi Cheeso,

your self extractor is amazing, thank you for your knowledge.

I have to make a self extracting file that execute a exe inside when extracting, I did it thanks to you :)

I just have a problem with the ConsoleApplication, I use it to provide transparency to the clients, they just have to double click to the exe file and everything is done...the first time it works, BUT if the client want to re-run exe, it won't overwrite the existing files and unfortunately won't execute the exe inside.

I thought to RemoveUnpackedFilesAfterExecute=true but if client cancel/close the execution of the exe file, the RemoveUnpackedFilesAfterExecute will not be executed.

I know that I just have to pass the "-o" parameter to the exe but client will not do this (they don't know, they just won't to click in exe).

I just want to overwrite the existing files using ConsoleApplication by double clicking the exe file...

Can you help me to handle this? Thank you !!

Kinf Regards

Coordinator
Oct 15, 2009 at 10:46 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Coordinator
Oct 15, 2009 at 11:00 AM

Hey Fred, I liked your idea so I created a new workitem for it, and implemented something that should satisfy you.

There's a new option called ExtractExistingFile.  Set it to the thing you want, to default the behavior of the generated SFX. 

You need v1.9.0.23 to get this feature.

Oct 15, 2009 at 11:32 AM

Great!

I saw the same option for zip behavior but include it for self extract file is a very good idea.

Well done !!

 

By the way, i've found something strange. PostExtractCommandLine doen't like name with blank..(Hello world.exe will not work, but HelloWorld.exe =>ok). 

 

kind Rgs

Fred.


Coordinator
Oct 15, 2009 at 12:08 PM

Hey Fred, thanks for the feedback.

On the commandline:  the way it works is this:  If there is no whitespace in the commandline argument, the argument is treated as the name of a program, and that program is run.  If there is some whitespace in the commandline argument, the arg is split.  The first part is treated as the filename of the program, and the remainder is the set of arguments to the program.  If you have a program name (or path) that includes a space, it will break this logic.

I'll get that fixed, too. 

 

 

Coordinator
Oct 15, 2009 at 12:08 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Oct 15, 2009 at 3:40 PM

Hey Cheeso,

You are a star! My upgrade self extracting exe is working perfectly.

Thank you,

Ste

Coordinator
Oct 15, 2009 at 3:50 PM

Glad to hear it, Ste!

Coordinator
Oct 15, 2009 at 4:05 PM

Fred --

Spaces in the commandline program are now supported.  If the program filename or path has spaces, you need to surround the command with double-quotes, just as you would at a command prompt.

Get v1.9.0.24 for this fix.

-Cheeso

 

Oct 19, 2009 at 9:22 AM

Hello Cheeso,

Thanks for your support, it help me a lot !

As I said you, i'm creating a multiple selfextracting file generator using a xml in input (with several directories to zip).

Everything worked well (browse, etc) but now strange behaviour...when I browse a xml file and do the call 'SaveSelfExtractor', I have a exception "Errors compiling the extraction logic!  C:\Documents and Settings\fdv\Local Settings\Temp\Ionic.Zip-2009oct.19-111744-1.cs". I'm using XP Pro..

Can you explain me why I have this suddenly ?

Hope there is solution...

Kind Regards.

Fred.

Oct 19, 2009 at 9:49 AM

Re,

I've checked for the openFileDialog who caused the exception, and after changing to a FolderBrowserDialog, it works.

Why it doesn't work with a openFileDialog ? I don't understand...really.

Let me know.

Fred.

Oct 19, 2009 at 12:54 PM

Hello,

After investigation I've found the problem !

I don't know why, after removing my personal .ico for self extracting files everything works fine.

So, I will use the default icon.

^^

Coordinator
Oct 19, 2009 at 6:56 PM

Fred, if you send me the contents of that .cs file, I may be able to help explain the error you get when producing an SFX with a custom .ico file.  You can also look for yourself - if you use the latest version of DotNetZip (either v1.8 or v1.9), then the compilation errors will be documented at the bottom of that source file.

I have no idea what you are talking about with the openFileDialog vs FolderBrowserDialog.  Can you explain what that relates to?

 

 

Oct 20, 2009 at 8:23 AM

Cheeso,

I will try to explain.

What : I get this error message "Problem occurs while creating files : Errors compiling the extraction logic ! c:\..\Ionic.Zip***.cs"

When : - when I want to add my self icon for the self Extracting file (not a problem I've restored the default icon)

           - When I publish my project, and install it to a another machine (like server 2003). I run my program and get this message too (using default icon)..

Can you explain what is this error exactly ? what triggers it ?  And why this behavior when I run the exe in another OS, is there something missing? something that I have to add in addition to the dll ? Or server 2003 have to have the 3.5 SP1 framework installed ?

 

Let me know.

Fred.

 

Oct 20, 2009 at 8:41 AM

sorry,

I have this error when I let the default Icon 

 

// ------------------------------------------------------------------
// Errors during compilation: 
//
//   Ionic.Zip-2009Oct20-103635-1.cs(0,0): error CVT1105: cannot seek in file
//
//   Ionic.Zip-2009Oct20-103635-1.cs(0,0): error CS1583: 'c:\Documents and Settings\admin\Local Settings\Temp\CSCB6.tmp' is not a valid Win32 resource file
//

// ------------------------------------------------------------------

// Errors during compilation: 

//

//   Ionic.Zip-2009Oct20-103635-1.cs(0,0): error CVT1105: cannot seek in file

//

//   Ionic.Zip-2009Oct20-103635-1.cs(0,0): error CS1583: 'c:\Documents and Settings\admin\Local Settings\Temp\CSCB6.tmp' is not a valid Win32 resource file

//

Fred.

 

 

Oct 20, 2009 at 10:24 AM

Ok,

I can explain the bug and I will try to be clear...

 

I have 2 browse, one for my xml input (tbXmlName) and one for the SFXfile directory output (tbDirName).

I don't know why but when I browse to my xml file (i.e: C:\Documents and Settings\fdv\Desktop\vdb\alldevices.xml) which content my SFXFilename (_fileTitle) and specify these options :

                    SelfExtractorSaveOptions sfxOptions = new SelfExtractorSaveOptions();
                    sfxOptions.Flavor = SelfExtractorFlavor.ConsoleApplication;
                    sfxOptions.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;
                    sfxOptions.IconFile = "client_vandenborre.ico";
                    sfxOptions.Quiet = true; // hides the window after startup
                    sfxOptions.DefaultExtractDirectory = "%SystemRoot%\\";
                    if (!File.Exists(_zipRoot + "\\vaste_gegevens_rechts\\" + _fileLanguage + "\\vandenborre_screensaver\\install\\screensaverTemplate.exe"))
                        throw new Exception("vandenborre_screensaver\\install\\screensaverTemplate.exe not found. Please check the file name.");
                    sfxOptions.PostExtractCommandLine = "vandenborre_screensaver\\install\\screensaverTemplate.exe";
                    zip1.SaveSelfExtractor(tbDirName.Text + "\\" + _fileTitle + ".exe", sfxOptions);
SelfExtractorSaveOptions sfxOptions = new SelfExtractorSaveOptions();

sfxOptions.Flavor = SelfExtractorFlavor.ConsoleApplication;

sfxOptions.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;

sfxOptions.IconFile = "client_vdb.ico";

sfxOptions.Quiet = true; // hides the window after startup

sfxOptions.DefaultExtractDirectory = "%SystemRoot%\\";

zip1.SaveSelfExtractor(tbDirName.Text + "\\" + _fileTitle + ".exe", sfxOptions);

I have this error : 

Ionic.Zip-2009oct.20-114925-1.cs(0,0): error CS1567: Error generating Win32 resource: Error reading icon 'c:\Documents and Settings\fdv\Desktop\vdb\client_vdb.ico' -- The system cannot find the file specified. 

 

...seems like the icon link was affected by the browse..

=> If I don't browse when I execute my program, client_vdb.ico is found in the client_vdb.ico.deploy

 

Why does the saveSelfExtractor looking for 'c:\Documents and Settings\fdv\Desktop\vdb\' path ?? I didn't mentionned it anywhere except to read my xml file...

I've tried to change the icon link sfxOptions.IconFile = "test\\client_vdb.ico"; and guess what..Error reading icon 'c:\Documents and Settings\fdv\Desktop\vdb\test\client_vdb.ico' -- The system cannot find the file specified. 

 

Please help me !!!

 

Fred.

Coordinator
Oct 20, 2009 at 3:39 PM

Fred, I'm trying to understand exactly what problem or problems you are experiencing.

I understand that you have problems using the default icon on Windows Server 2003, but not on your XP Pro machine.  And also, you have different problems when specifying a custom icon, on any machine.  I'm happy to work through these things but we need to keep them separate so I can understand what is happening, and what specific problem we are trying to solve.  

Some recommendations

  1. Regarding the problems with the default icon, yes, the Windows Server 2003 machine must have .NET Framework v3.5 SP1 installed.  The icon files in Windows changed for Windows Vista - there is now a new image format supported by .ico files.   Support for the new Vista icon files in the .NET C# compiler (which is used when producing a SFX file) came with .NET 3.5 SP1  (or .NET 2.0 SP1, if you are running .NET 2.0).   The default icon in DotNetZip includes an image in the new-for-Windows-Vista format.  If you don't have the current .NET Framework patch, then the C# Compiler will generate the problem you reported:  error CVT1105: cannot seek in file, at runtime, when referencing a Windows Vista icon, such as the default icon.  Even if you don't use the default icon when creating a DotNetZip SFX, it's a good idea to make sure you have the latest .NET service pack, on all machines. 

  2. When specifying a custom .ico file, why do you not specify the full path for your .ico file ?  You are specifying "client_vdb.ico".  It seems that DotNetZip is pre-pending a relative path ('c:\Documents and Settings\fdv\Desktop\vdb\').   I don't know where that path comes from.  Could it be your current working directory?   In any case you can avoid this by using a full path.   

Oct 21, 2009 at 2:55 AM

Hi,

I just downloaded the latest version DotNetZip v1.9.0.24  but I could not find SelfExtractorSaveOptions class in there. Is there any thing missing from this release??

Regards

Coordinator
Oct 21, 2009 at 7:22 AM

Not sure why you can't find it. Maybe you are referencing an older binary. Check ZipFile.LibraryVersion - it will tell you the version of DotNetZip that you are running against.

I just checked the .chm file, which is generated from the source code. It includes the doc for SelfExtractorSaveOptions.

 

Nov 7, 2009 at 9:26 PM

Looks like you've done a great deal of work on this and that's awesome. Thanks for your hard work.

I would like to use the latest changes you have made but I can't get the source to compile (pulled it directly from SVN). Is there a place I can get the latest DLL?

Here are a few errors I get when trying to compile:

1. Missing singing file Ionic.snk

2. Error reading resource file 'dotnetzip\Zip Partial DLL\Resources\ZippedResources.zip' -- 'The system cannot find the file specified.' Zip Partial DLL

Coordinator
Nov 7, 2009 at 10:46 PM

Get the devkit from http://dotnetzip.codeplex.com/Release/ProjectReleases.aspx

The default release is v1.8.  You don't want that.  You want the v1.9 release.  Look in the far-right side, near the top, you'll see a box with release options.

When you click it you'll get a list of downloads.
Click the Devkit download. It has the latest DLL, the helpfile, and so on.  

Nov 7, 2009 at 10:50 PM

Duh! He he he, thanks.

I did get it but didn't realize the latest build with the desired changes was there.

Nov 30, 2009 at 5:28 PM

Hello~~

Is it possible to set  DefaultExtractDirectory always same as the file location itself?
In other words, I can extract zip to the directory where I execute it.

Thank you  

Nov 30, 2009 at 5:31 PM

oops...

I just find out....
the solution is don't set "DefaultExtractDirectory" property.