Menu

#65 Cancel installation / improved progress bar

closed-out-of-date
NSIS (71)
6
2006-06-17
2005-06-13
No

Patch to...

(1) Allow an installation to be canceled. The script
must enable the Cancel button; for example:

Section -PreInstall
GetDlgItem $0 $HWNDPARENT 2
EnableWindow $0 1
SectionEnd

(2) Add "filesize" option to InstProgressFlags command.
When selected, the installer progress bar advances
based on the number of bytes copied, not the number of
script commands (the uninstaller progress bar is still
driven by script execution).

(3) Enhanced the plugin DLL interface to expose the new
cancellation and progress bar features. This can be
used to provide a seamless user interface when a plugin
installs files (e.g. unzip, download, etc.). The user
will never know if NSIS is copying files embedded in
the installer, or extracting from an external ZIP file.

Discussion

  • John McNamee

    John McNamee - 2005-06-13

    Patch

     
  • Amir Szekely

    Amir Szekely - 2005-06-21

    Logged In: YES
    user_id=584402

    Thanks a lot for your patch.

    I have a few comments and questions:

    * The Cancel button can be enabled automatically in
    CEXEBuild::ProcessPages (add PF_BACK_ENABLE to p->flags).

    * The Cancel button should be disabled after the user clicks
    it so the user will know something is happening.

    * It seems it's possible for the user to click the Cancel
    button before install_thread_running is set. You can
    probably avoid thread synchronization by setting
    install_thread_running after CreateThread and resetting when
    processing WM_NOTIFY_INSTPROC_DONE. This way it'll be
    synchronized by the message loop.

    * There shouldn't be two progress bar modes. The new one
    should be the only one.

    * I prefer the progress bar length to be combined from code
    size and file size. The code_size field could be calculated
    at compile-time for this. Also, the units for the file size
    extraction can be OBUFSIZE bytes. This will make it simpler,
    will avoid calculations and I believe it will balance code
    and file extraction nicely.

    * There's no need to update the progress in case extraction
    fails. The installation will stop anyway.

    * I don't see how plug-ins can use the interface to attach
    their own progress. If they change progress_bar_len, the
    progress will suddenly jump back. There needs to be a way to
    set the progress bar length ahead, before anything is
    executed. I think plug-in patch can be delayed to a future
    patch, unless you already have a good idea for handling this
    problem.

     
  • Amir Szekely

    Amir Szekely - 2005-06-21
    • priority: 5 --> 6
     
  • Amir Szekely

    Amir Szekely - 2005-06-21

    Logged In: YES
    user_id=584402

    A couple more I just thought about:

    * ui_st_updateflag should be restored if the installation is
    canceled, in case some command that prints text (DetailPrint
    for example), will be used in .onUserAbort. It should also
    be restored for the Aborted text that should be printed.

    * There should be a new callback that will be called when
    the installation is canceled inside a section. Or there
    should be a new command that will allow the user to check
    for that. EW_IFFLAG can probably be used for that.

    * GetCompressedDataFromDataBlock is not called just from
    EW_EXTRACTFILE. Instructions that use it should update
    code_size accordingly.

     
  • John McNamee

    John McNamee - 2005-06-26

    Logged In: YES
    user_id=1291384

    I've uploaded progress.2.patch.

    > * The Cancel button can be enabled automatically in
    > CEXEBuild::ProcessPages (add PF_BACK_ENABLE to p->flags).
    >
    > * There shouldn't be two progress bar modes. The new one
    > should be the only one.

    I originally tried to create a patch that wouldn't change
    ANY behavior of existing installers. Not having that as a
    requirement certainly simplifies things!

    > * I prefer the progress bar length to be combined from code
    > ...
    >
    > * The Cancel button should be disabled after the user clicks
    > it so the user will know something is happening.
    >
    > * ui_st_updateflag should be restored if the installation is
    > canceled, in case some command that prints text (DetailPrint
    > for example), will be used in .onUserAbort. It should also
    > be restored for the Aborted text that should be printed.

    Done.

    > * It seems it's possible for the user to click the Cancel
    > button before install_thread_running is set.

    This wasn't an issue in the original patch, because it took
    script commands executed from within the install thread to
    enable the Cancel button. It's now possible to click Cancel
    before the install thread starts, but I don't think it
    matters. Unless the system is seriously screwed up (in
    which case you've got bigger problems), the install thread
    is going to start in a matter of milliseconds, and it will
    respond to the Cancel.

    > * GetCompressedDataFromDataBlock is not called just from
    > EW_EXTRACTFILE. Instructions that use it should update
    > code_size accordingly.

    Are there any other instructions that extract large chunks
    of data?

    > * There's no need to update the progress in case extraction
    > fails. The installation will stop anyway.

    Where does my patch do this?

    > * There should be a new callback that will be called when
    > the installation is canceled inside a section. Or there
    > should be a new command that will allow the user to check
    > for that. EW_IFFLAG can probably be used for that.

    I added an IfCancel command. .onUserAbort can use IfCancel
    if it cares where the abort is occurring; I suspect
    many/most installers won't care.

    > * I don't see how plug-ins can use the interface to attach
    > their own progress.

    The basic idea is that the script uses AddSize and/or
    SectionSetSize to account for the size of the external
    files. The plugin uses update_progress and check_cancel (in
    plugin_extra_parameters) to integrate with NSIS.

    I moved progress_bar_pos and progress_bar_len into
    exec_flags when I started working on my patch, but it turns
    out they don't need to be there. They're gone now.

    I've written a plugin that seamlessly installs from external
    zip files, so I've got a proof of concept. Unfortunately, I
    can't release it yet (I can send you a copy privately if
    you'd like).

     
  • John McNamee

    John McNamee - 2005-06-26

    Path version 2

     
  • Amir Szekely

    Amir Szekely - 2005-07-02

    Logged In: YES
    user_id=584402

    Nice to see you're still working on this. Most patches
    disappear after the first batch of comments.

    I've numbered the comments this time, for easy referencing.

    1. While the better progress should be the default, the same
    can't be said for the cancel button. If the script isn't
    prepared to clean up after the user clicks cancel during
    installation, the cancel button shouldn't be enabled. There
    should therefore be a command to enable the cancel button.
    It would be nice to make it work per instfiles page too.
    That means it should work both outside and inside a PageEx
    block.

    2. Why is install_thread being passed the dialog handle and
    not the progress bar handle?

    3. A new field in the section structure can contain a
    pre-calculated value of the total progress for the section.
    There's no need to calculate it in install_thread.

    4. Why is progress_bar_pos recalculated after each section
    is executed?

    5. I don't think there is a need to check if the
    installation was canceled after it finishes (line 313 of the
    patch).

    6. Why use PostMessage to send WM_NOTIFY_INSTPROC_DONE and
    not NotifyCurWnd?

    7. Why keep hInstallThread as a static variable and not
    close it right away?

    8. Please add code comments on position calculations in
    ExecuteCodeSegment.

    9. Add a comment in EW_REGISTERDLL that explains
    original_quit_flag is needed for plug-in calls in .onUserAbort.

    10. In __ensuredata and other decompression functions retval
    is set to an error value, the progress bar is updated and
    only then the function returns. I don't think there is need
    to update the progress bar in case of an error. It won't
    reach the end anyway.

    11. It doesn't seem like the progress bar is properly
    updated if files are skipped for some reason. For example:

    Goto +2
    File bigfile.dat

    or even:

    SetOverwrite off
    File bigfile.dat
    File bigfile.dat # will be skipped

    12. There's no need to restore ui_st_updateflag to its
    previous value after .onUserAbort. There's only a need to
    clear the LSB so update_status_text will add new lines
    instead of appending to the last line.

    13. WriteRegBin (EW_WRITEREG) calls
    GetCompressedDataFromDataBlockToMemory and so does
    WriteUninstaller (EW_WRITEUNINSTALLER).

    14. The system doesn't have to be screwed up in order for
    the cancel button to be clicked before install_thread
    starts. Being busy is enough.

    15. InterlockedCompareExchange is not available on Windows 95.

    16. Please upload the plug-in proof of concept when you can
    release it. I don't need a copy yet, thanks.

     
  • Amir Szekely

    Amir Szekely - 2005-10-28

    Logged In: YES
    user_id=584402

    Any progress?

     
  • Amir Szekely

    Amir Szekely - 2006-06-17
    • status: open --> closed-out-of-date
     
  • Nobody/Anonymous

    Logged In: NO

    any news?

     

Log in to post a comment.

Oh no! Some styles failed to load. 😵 Please try reloading this page