Sdílet prostřednictvím


Přidání vlastních akcí do indikátoru průběhu

vlastní akce mohou přidat informace o čase a průběhu do ovládacího prvku ProgressBar. Další informace o vytvoření dialogového okna zobrazení akce s Indikátorem průběhu najdete v tématu Vytvoření ovládacího prvku ProgressBar.

Všimněte si, že do balíčku Instalační služby systému Windows musí být přidány dvě vlastní akce, aby bylo možné přesně hlásit čas a informace o průběhu do indikátoru ProgressBar. Jedna vlastní akce musí být odložený úkol. Tato vlastní akce by měla dokončit vámi zvolenou instalaci a při spuštění instalačního skriptu poslat hodnoty jednotlivých přírůstků do ovládacího prvku ProgressBar. Druhá vlastní akce musí být vlastní akcí okamžitého spuštění, která informuje ProgressBar, kolik z nich se má přidat k celkovému počtu během fáze získávání a generování skriptu instalace.

Přidání vlastní akce do ProgressBar

  1. Rozhodněte, jak bude vlastní akce popisovat její průběh. Například vlastní akce, která instaluje klíče registru, může zobrazit zprávu o průběhu a aktualizovat ProgressBar pokaždé, když instalační program zapíše jeden klíč registru.

  2. Každá aktualizace vlastní akce změní délku ProgressBar o konstantní přírůstek. Zadejte nebo vypočítejte počet záškrtů v každém přírůstku. Posun délky ProgressBar obvykle odpovídá instalaci jednoho bajtu. Pokud například instalační program nainstaluje přibližně 10 000 bajtů, když zapisuje jeden klíč registru, můžete určit, že při přírůstku je 10 000 ticků.

  3. Zadejte nebo vypočítejte celkový počet tiků, které uživatelská akce přidá k délce ProgressBar. Počet tiků přidaných vlastní akcí se obvykle vypočítá takto: (přírůstek tiků) x (počet položek). Pokud například vlastní akce zapíše 10 klíčů registru, instalační program nainstaluje přibližně 1 0000 bajtů a instalační program proto musí zvýšit odhad konečné celkové délky ProgressBar o 1 00000 záškrtů.

    Poznámka

    Aby bylo možné tuto vlastní akci vypočítat dynamicky, musí obsahovat část, která se okamžitě spustí během generování skriptu. Počet tiků hlášených vaší vlastní akcí odloženého spuštění se musí rovnat počtu tiků přidaných k celkovému počtu tiků akcí okamžitého provedení. Pokud tomu tak není, zbývající čas hlášený ovládacím prvku TimeRemaining text nebude přesný.

     

  4. Vlastní akci oddělte do dvou částí kódu: oddíl, který se spouští během fáze generování skriptu, a oddíl, který se spouští během fáze provádění instalace. Můžete to udělat pomocí dvou souborů, nebo použít jeden soubor v závislosti na režimu spuštění instalačního programu. Následující ukázka používá jeden soubor a zkontroluje stav instalace. Oddíly ukázky jsou podmíněny podmínkami spuštění v závislosti na tom, jestli je instalační program ve fázi provádění nebo generování instalačního skriptu.

  5. Část, která se spouští během generování skriptu, by měla navýšit odhad konečné délky ProgressBar o celkový počet kroků ve vlastní akci. To se provádí odesláním zprávy o pokroku ProgressAddition.

  6. Část, která se spouští během fáze provádění instalace, by měla nastavit text zprávy a šablony, aby informovala uživatele o tom, co vlastní akce provádí, a aby nasměrovala instalační program k aktualizaci ovládacího prvku ProgressBar. Informujte například instalačního programu, aby přesunul indikátor ProgressBar o jeden přírůstek a odeslal explicitní zprávu o průběhu každé aktualizace. V této části je obvykle smyčka, pokud nějaká vlastní akce něco instaluje. Při každém průchodu touto smyčkou může instalační program nainstalovat jednu referenční položku, jako je klíč registru, a aktualizovat ovládací prvek ProgressBar.

  7. Přidejte vlastní akci okamžitého spuštění do balíčku Instalační služby systému Windows. Tato přizpůsobená akce informuje ProgressBar, o kolik se má posunout během fází získávání a generování skriptů instalace. Pro následující ukázku je zdrojem knihovna DLL vytvořená kompilováním vzorového kódu a cílem je vstupní bod CAProgress.

  8. Do balíčku Instalační služby systému Windows přidejte vlastní akci odloženého spuštění. Tato vlastní akce dokončí kroky skutečné instalace a informuje ProgressBar o tom, o kolik se má posunout pokrok na panelu v době, kdy instalační program spustí instalační skript. Pro následující ukázku je zdrojem knihovna DLL vytvořená kompilováním vzorového kódu a cílem je vstupní bod CAProgress.

  9. Naplánujte obě vlastní akce mezi InstallInitialize a InstallFinalize v tabulce InstallExecuteSequence. Odložená vlastní akce by měla být naplánována okamžitě po vlastní akci okamžitého spuštění. Instalační program nespustí odloženou vlastní akci, dokud se skript nespustí.

Následující ukázka ukazuje, jak lze přidat vlastní akci do ProgressBar. Zdrojem obou vlastních akcí je knihovna DLL vytvořená kompilováním ukázkového kódu a cílem obou vlastních akcí je vstupní bod CAProgress. Tato ukázka neprovádí žádné skutečné změny systému, ale pracuje s indikátorem ProgressBar jako při instalaci 10 referenčních položek, které mají velikost přibližně 10 000 bajtů. Instalační program aktualizuje zprávu a ProgressBar pokaždé, když nainstaluje referenční položku.

#include <windows.h>
#include <msiquery.h>
#pragma comment(lib, "msi.lib")

// Specify or calculate the number of ticks in an increment
// to the ProgressBar
const UINT iTickIncrement = 10000;
 
// Specify or calculate the total number of ticks the custom 
// action adds to the length of the ProgressBar
const UINT iNumberItems = 10;
const UINT iTotalTicks = iTickIncrement * iNumberItems;
 
UINT __stdcall CAProgress(MSIHANDLE hInstall)
{
    // Tell the installer to check the installation state and execute
    // the code needed during the rollback, acquisition, or
    // execution phases of the installation.
  
    if (MsiGetMode(hInstall,MSIRUNMODE_SCHEDULED) == TRUE)
    {
        PMSIHANDLE hActionRec = MsiCreateRecord(3);
        PMSIHANDLE hProgressRec = MsiCreateRecord(3);

        // Installer is executing the installation script. Set up a
        // record specifying appropriate templates and text for
        // messages that will inform the user about what the custom
        // action is doing. Tell the installer to use this template and 
        // text in progress messages.
 
        MsiRecordSetString(hActionRec, 1, TEXT("MyCustomAction"));
        MsiRecordSetString(hActionRec, 2, TEXT("Incrementing the Progress Bar..."));
        MsiRecordSetString(hActionRec, 3, TEXT("Incrementing tick [1] of [2]"));
        UINT iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONSTART, hActionRec);
        if ((iResult == IDCANCEL))
            return ERROR_INSTALL_USEREXIT;
              
        // Tell the installer to use explicit progress messages.
        MsiRecordSetInteger(hProgressRec, 1, 1);
        MsiRecordSetInteger(hProgressRec, 2, 1);
        MsiRecordSetInteger(hProgressRec, 3, 0);
        iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hProgressRec);
        if ((iResult == IDCANCEL))
            return ERROR_INSTALL_USEREXIT;
              
        //Specify that an update of the progress bar's position in
        //this case means to move it forward by one increment.
        MsiRecordSetInteger(hProgressRec, 1, 2);
        MsiRecordSetInteger(hProgressRec, 2, iTickIncrement);
        MsiRecordSetInteger(hProgressRec, 3, 0);
 
        // The following loop sets up the record needed by the action
        // messages and tells the installer to send a message to update
        // the progress bar.

        MsiRecordSetInteger(hActionRec, 2, iTotalTicks);
       
        for( int i = 0; i < iTotalTicks; i+=iTickIncrement)
        {
            MsiRecordSetInteger(hActionRec, 1, i);

            iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hActionRec);
            if ((iResult == IDCANCEL))
                return ERROR_INSTALL_USEREXIT;
          
            iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hProgressRec);
            if ((iResult == IDCANCEL))
                return ERROR_INSTALL_USEREXIT;
   
            //A real custom action would have code here that does a part
            //of the installation. For this sample, code that installs
            //10 registry keys.
            Sleep(1000);
                    
        }
        return ERROR_SUCCESS;
    }
    else
    {
        // Installer is generating the installation script of the
        // custom action.
  
        // Tell the installer to increase the value of the final total
        // length of the progress bar by the total number of ticks in
        // the custom action.
        PMSIHANDLE hProgressRec = MsiCreateRecord(2);

         MsiRecordSetInteger(hProgressRec, 1, 3);
            MsiRecordSetInteger(hProgressRec, 2, iTotalTicks);
        UINT iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hProgressRec);
           if ((iResult == IDCANCEL))
            return ERROR_INSTALL_USEREXIT;     
        return ERROR_SUCCESS;
     }
}