Set Taskbar button progress

From NSIS Wiki

Description

Provides control over the progress indicator available through ITaskBarList3, available from Windows 7.

This header is not intended as a replacement for the TaskbarProgress plug-in.

The TaskbarProgress plug-in can automatically handle progress display on dialogs with a progressbar, most typically the InstFiles page.

Instead, it is intended for pages where taskbar progress indication is desired without use of a dialog progressbar, and for functionality not offered by the TaskbarProgress plug-in at this time.

This header is scripting-friendly and does not require initialization, Windows version detection, or clean-up.

Usage

Usage of this header has been made to be as simple as possible.

  • Include this header in your sript.
!include "TBProgress.nsh"
  • Call the desired command. For example, for 50% PROGRESS:
${TBProgress} 50

The commands themselves ensure that the ITaskBarList3 interface has been created and is valid for use - so you can use these commands regardless of Windows platform, and without having to worry about initialization and whether or not your installer is running silently.

There is one caveat: You should not use these commands -before- a taskbar button conceivably can be displayed. I.e. do not use these commands in .onInit. .onGUIInit is the earliest moment that these commands may be used.

Commands

The following commands are available:

${TBProgress} Value

Shorthand to setting the current progress as Value percentage.

  • You should call this command whenever a process with known progress takes place within your installer.
  • Overrides ${TBProgress_State} Indeterminate and sets ${TBProgress_State} Normal by design of ITaskBarList3.
  • Can be used under ${TBProgress_State Paused and ${TBProgress_State} Error states, although this is not recommended as it will confuse end-users.

${TBProgress_Progress} Value MaxValue

Sets the current progress to Value as a portion of MaxValue

  • This command is provided in case you need exact control over the progress value, allowing you to set a custom maximum value.

${TBProgress_State} NoProgress

Returns the taskbar button to a normal state (no progressbar).

  • You should call this command whenever you are done showing progress.
  • You are not required to call this command before exiting the installer.

${TBProgress_State} Normal

Sets the taskbar button to a normal (green) progressbar state.

  • You may call this command to end a ${TBProgress_State} Paused or ${TBProgress_State} Error command state and return to a regular state.

${TBProgress_State} Paused

Sets the taskbar button to a paused (yellow) progressbar state.

  • You should call this command whenever progress is paused due to an event that requires user input.
  • You should call ${TBProgress_State} Normal once the event has passed and progress will continue.
  • You should call ${TBProgress_State} NoProgress once the event has passed and progress will NOT continue.

${TBProgress_State} Error

Sets the taskbar button to an error (red) progressbar state.

  • You should call this command whenever progress has halted without hope for continuation.
  • You should call ${TBProgress_State} NoProgress once this indication is no longer required and the process for which you were indicating progress has been halted.
  • Although you may continue progress within this state, or revert to a ${TBProgress_State} Normal state, this is not recommended as it will confuse end-users.

${TBProgress_State} Indeterminate

Sets the taskbar button to an indeterminate (green marquee) progressbar state.

  • You should call this command whenever a process with UNKNOWN progress takes place within your installer which must complete in order for your installer to continue. For example, if you are running a secondary installer from your own installer, and cannot get its exact progress, use this command to show the user that the installer is performing work.

${TBProgress_Init}

Initializes the ITaskBarList3 interface, which is stored in the $ITaskBarList3 variable.

  • This command is provided for programmers who wish to work directly with the ITaskBarList3 COM interface.
  • You are not required to call this command in order to use the other commands - they all call this command internally and its code is only evaluated if not already done so.


The Script Code / Header

!include "LogicLib.nsh"
 
!ifndef CLSCTX_INPROC_SERVER
    !define CLSCTX_INPROC_SERVER  1
!endif
 
!define CLSID_ITaskbarList    {56fdf344-fd6d-11d0-958a-006097c9a090}
 
!define IID_ITaskbarList3     {ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}
!define ITaskbarList3->SetProgressState      $ITaskbarList3->10
!define ITaskbarList3->SetProgressValue      $ITaskbarList3->9
 
!define TBPF_NOPROGRESS       0x00000000 ; Normal state / no progress bar
!define TBPF_INDETERMINATE    0x00000001 ; Marquee style progress bar
!define TBPF_NORMAL           0x00000002 ; Standard progress bar
!define TBPF_ERROR            0x00000004 ; Red taskbar button to indicate an error occurred
!define TBPF_PAUSED           0x00000008 ; Yellow taskbar button to indicate user attention
                                         ; (input) is required to resume progress
 
Var ITaskbarList3
 
!macro TBProgress_Init
  !ifndef TBProgressInitialized
    !define TBProgressInitialized
    ${Unless} ${Silent}
      System::Call "ole32::CoCreateInstance( \
        g '${CLSID_ITaskbarList}', \
        i 0, \
        i ${CLSCTX_INPROC_SERVER}, \
        g '${IID_ITaskbarList3}', \
        *i .s)"
      Pop $ITaskbarList3
    ${Else}
      StrCpy $ITaskbarList3 0
    ${EndIf}
  !endif
!macroend
!define TBProgress_Init `!insertmacro TBProgress_Init`
 
!macro TBProgress_Progress Val Max
  ${TBProgress_Init}
  ${If} $ITaskbarList3 <> 0
      System::Call "${ITaskbarList3->SetProgressValue}(i$HWNDPARENT, l${Val}, l${Max})"
  ${EndIf}
!macroend
!define TBProgress_Progress `!insertmacro TBProgress_Progress`
 
!macro TBProgress Val
  ${TBProgress_Progress} ${Val} 100
!macroend
!define TBProgress `!insertmacro TBProgress`
 
!macro TBProgress_State State
  ${TBProgress_Init}
  ${If} $ITaskbarList3 <> 0
      System::Call "${ITaskbarList3->SetProgressState}(i$HWNDPARENT, i${TBPF_${State}})"
  ${EndIf}
!macroend
!define TBProgress_State `!insertmacro TBProgress_State`

Tips

Read the MSDN guidelines on proper (taskbar) progress usage.

For example:

It may be tempting to use a loop to flash a taskbar button yellow. However, this is
  1. highly annoying for end-users
  2. is not the correct command. ( See FlashWindowEx on MSDN instead )

Another example:

It may be tempting to show overall installer progress as x/N pages. Don't.

When using the TBProgress or TBProgress_Progress commands, consider changing the caption of the installer to indicate the progress value as a percentage.

When using the TBProgress_Indeterminate state, consider also using the SetCursor plug-in to set a WAIT cursor ONLY IF appropriate! (e.g. if you use a command which may significantly affect the system's responsiveness)

When using the TBProgress_Error state, consider using the NotifyIcon plug-in to alert the user to the error via the notification area of the taskbar.

You may use TBProgress_Error to indicate that the user cannot continue installation, even if you are not indicating any progress. For example: if your installer cannot continue due to any missing prerequisites, you may set a red taskbar button using:

${TBProgress_State} Error ; Set error state (red progressbar)
${TBProgress} 100 ; Set progress to 100% to cover progressbar button

If all you need is to show InstFiles progress, please do use the TaskbarProgress plug-in

Personal tools
donate