MAKEMSI quickly and reliably creates MSI files in a non-programmatic way
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
[Bottom][Contents][Prev]: Progress Bar - More Detail[Next]: Read Me dialogs (rtf formatted text in scrollable control)
Have your say! Join the MAKEMSI discussion list or view archive! Suggest improvements. No question too simple or too complex.
\->Tips and Tricks->User Interface Tips->Progress Bar - Move Bar

Progress Bar - Move Bar

This code demonstrates how you can move the progress bar during a lengthy custom action. While it demonstrates VBSCRIPT, the same details apply to all custom action types.

Some facts (if you want to end at 100%):

EXAMPLE.MM

The following demonstrates the basics of moving the progress bar.

<$VbsCa Binary="TestProgressBar.vbs">
    ;--- Progress Bar Initialization ----------------------------------------
    <$VbCaProgressTickFunctions>

    <$VbsCaEntry "DoDeferredInstallation">
        ;--- Define (to this script) the maximum that ProgressTicksUse() can consume ---
        #define TICKS_DoDeferredInstallation   10000000
        ProgressTicksAdd <$TICKS_DoDeferredInstallation>

        ;--- Now do some installation stuff ---------------------------------
        dim i
        for i = 1 to 10
            ;--- Do something that takes some time... -----------------------
            MsgBox "Doing installation stuff #" & i, vbInformation, "DEBUG"

            ;--- Indicate we have done something (in this case 10% of the work) ---
            ProgressTicksUse 1000000
        next

        ;--- Use any left over ----------------------------------------------
        ProgressTicksUse -1
    <$/VbsCaEntry>

    <$VbsCaEntry "AddTicksToWindowsInstaller">
        ;--- Need an IMMEDIATE CA to add to total tick count ----------------
        ProgressTicksAdd <$TICKS_DoDeferredInstallation>
    <$/VbsCaEntry>
<$/VbsCa>
<$VbsCaSetup Binary="TestProgressBar.vbs" Entry="AddTicksToWindowsInstaller" Seq="CreateShortcuts-" Condition="<$CONDITION_INSTALL_ONLY>" TYPE="IMMEDIATE">
<$VbsCaSetup Binary="TestProgressBar.vbs" Entry="DoDeferredInstallation"     Seq="CreateShortcuts-" Condition="<$CONDITION_INSTALL_ONLY>">

ProgressTicks Code

The following shows the supporting code that needs to be included ASAP after the "VbsCa command.

#define  VERSION_VbCaProgressTickFunctions  06.232
#define? PROGRESSTICKS_DEBUG_MAX_MSGBOX     0          ;;Set to max number of dialogs you want to see (or click on!)
#define? PROGRESSTICKS_DEBUG_LOG            Y          ;;In Verbose and any "text" log
#(  '<?NewLine>'
    #define VbCaProgressTickFunctions

    ;--- Set up global variables reuired by Progress code --------------------
    dim   MaxMsgBoxes        : MaxMsgBoxes = <$PROGRESSTICKS_DEBUG_MAX_MSGBOX>
    dim   TotalProgressTicks : TotalProgressTicks = clng(0)
    <?NewLine><?NewLine>

    <?NewLine><?NewLine>
    ;=====================================================================
    function AddCommas(Numb)
    ;=====================================================================
        AddCommas = FormatNumber(Numb, 0, True, True)
    end function


    <?NewLine><?NewLine>
    ;=====================================================================
    sub TicksMsg(ByVal Msg)
    ;=====================================================================
        ;--- Output to verbose (and any "text") log -------------------------
        err.clear()
        #if ['<$PROGRESSTICKS_DEBUG_LOG>' <> 'N']
            CaDebug 0, "[\[]PROGRESS TICKS[\]]: " & Msg
        #endif

        ;--- Display message box --------------------------------------------
        if  MaxMsgBoxes <> 0 then
            MaxMsgBoxes = MaxMsgBoxes - 1
            MsgBox Msg, vbInformation, "PROGRESS BAR TICKS DIAGNOSTIC"
        end if
    end sub


    <?NewLine><?NewLine>
    ;=====================================================================
    function MsgRc(ByVal MsRc)
    ;=====================================================================
        dim T : T = ""
        if  err.number <> 0 then
            T = vbCRLF & "err.number = 0x" & hex(err.number) & " - " & err.description
        end if
        if  MsRc <> 1 then
            T = vbCRLF & "Session.Message RC = " & MsRc & " (expected 1)" & T
        end if
        if  T <> "" then
            T = vbCRLF & T
        end if
        MsgRc = T
    end function


    <?NewLine><?NewLine>
    ;=====================================================================
    sub ProgressTicksAdd(Ticks2Add)
    ;=====================================================================
        ;--- Immediate of deferred? -----------------------------------------
        on error resume next
        dim Msg
        if  session.mode(msiRunModeScheduled) then
            ;--- Deferred ---------------------------------------------------
            TotalProgressTicks = clng(TotalProgressTicks + Ticks2Add)
            #(
                TicksMsg "Setting tick limit only as this is a deferred Custom Action."
                         & vbCRLF & vbCRLF
                         & "Added " & AddCommas(Ticks2Add) & ", the new total is " & AddCommas(TotalProgressTicks)
            #)

            ;--- Don't want ActionData messages to change bar ---------------
            err.clear()
            set oRec = Installer.CreateRecord(3)
            oRec.IntegerData(1) = ActionInfo
            oRec.IntegerData(2) = 0
            oRec.IntegerData(3) = 0
            MsgRc = session.message(msiMessageTypeProgress, oRec)
            set oRec = Nothing
            Msg = MsgRc(MsgRc)
            TicksMsg "Preventing ActionInfo from moving bar." & Msg
        else
            ;--- Tell Windows Installer how many ticks the CA will use ------
            err.clear()
            dim oRec : set oRec = Installer.CreateRecord(3)
            oRec.IntegerData(1) = ProgressAddition
            oRec.IntegerData(2) = Ticks2Add
            oRec.IntegerData(3) = 0
            dim MsgRc : MsgRc = session.message(msiMessageTypeProgress, oRec)
            set oRec = Nothing
            Msg = MsgRc(MsgRc)
            TicksMsg "Added " & AddCommas(Ticks2Add) & " ticks to the Windows Installer progress bar as this is an immediate Custom Action." & Msg
        end if

        ;--- Make sure err.number is 0 --------------------------------------
        err.clear()
    end sub

    <?NewLine><?NewLine>
    ;=====================================================================
    sub ProgressTicksUse(ByVal Ticks2Consume)
    ;=====================================================================
        ;--- We can't consume more ticks than we have added -----------------
        on error resume next
        dim Msg
        dim UseTicks : UseTicks = Ticks2Consume
        if  UseTicks = -1 then
            ;--- Asked to use the rest --------------------------------------
            UseTicks = TotalProgressTicks
        elseif UseTicks > TotalProgressTicks then
            ;--- More than we have so just use what we have -----------------
            UseTicks = TotalProgressTicks
        end if

        ;--- Remember what we have left -------------------------------------
        dim T
        if  UseTicks < 1 then
            ;--- No ticks left ----------------------------------------------
            if  Ticks2Consume = -1 then
                T = "all remaining"
            else
                T = AddCommas(Ticks2Consume)
            end if
            TicksMsg "Asked to use " & T & " ticks, but none left"
            exit sub
        end if
        TotalProgressTicks = clng(TotalProgressTicks - UseTicks)


        ;--- Output to progress bar -----------------------------------------
        dim oRec : set oRec = Installer.CreateRecord(3)
        oRec.IntegerData(1) = ProgressReport
        oRec.IntegerData(2) = UseTicks
        oRec.IntegerData(3) = 0
        dim MsgRc : MsgRc = session.message(msiMessageTypeProgress, oRec)
        set oRec = Nothing
        Msg = MsgRc(MsgRc)
        T = "Used " & AddCommas(UseTicks) & " ticks"
        if  Ticks2Consume <> UseTicks then
            T = T & " (" & AddCommas(Ticks2Consume) & " requested)"
        end if
        T = T & ", total now " & AddCommas(TotalProgressTicks)
        TicksMsg T & Msg

        ;--- Make sure err.number is 0 --------------------------------------
        err.clear()
    end sub
#)


Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.Please email me any feedback, additional information or corrections.
See this page online (look for updates)

[Top][Contents][Prev]: Progress Bar - More Detail[Next]: Read Me dialogs (rtf formatted text in scrollable control)


MAKEMSI© is (C)opyright Dennis Bareis 2003-2008 (All rights reserved).
Saturday May 28 2022 at 3:11pm
Visit MAKEMSI's Home Page
Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006, 2007, 2008 & 2009 for the Windows SDK (Windows Installer) area.