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]: Remote Desktop Shortcuts
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 for the Windows SDK (Windows Installer) area.This external link was OK when tested at 15 Nov 2008Please email me any feedback, additional information or corrections.
See this page online (look for updates)

[Top][Contents][Prev]: Progress Bar - More Detail[Next]: Remote Desktop Shortcuts


MAKEMSI© is (C)opyright Dennis Bareis 2003-2008 (All rights reserved).
Saturday November 15 2008 at 2:05pm
Visit MAKEMSI's Home PageThis external link was OK when tested at 7 Nov 2008

HTML page dated Mon, 29 Jan 2007 00:11:11 GMT
Microsoft awarded me an MVP (Most Valuable Professional award) in 2004, 2005, 2006 & 2007 for the Windows SDK (Windows Installer) area.This external link was OK when tested at 15 Nov 2008