Aggiunta di azioni personalizzate a ProgressBar

Le azioni personalizzate possono aggiungere informazioni sull'ora e sullo stato di avanzamento a un controllo ProgressBar . Per altre informazioni sulla creazione di una finestra di dialogo di visualizzazione delle azioni con progressBar, vedere Creazione di un controllo ProgressBar.

Si noti che due azioni personalizzate devono essere aggiunte al pacchetto di Windows Installer per segnalare in modo accurato le informazioni sull'ora e sullo stato di avanzamento a ProgressBar. Un'azione personalizzata deve essere un'azione personalizzata posticipata. Questa azione personalizzata deve completare l'installazione personalizzata e inviare gli importi dei singoli incrementi al controllo ProgressBar quando il programma di installazione esegue lo script di installazione. La seconda azione personalizzata deve essere un'azione personalizzata di esecuzione immediata che informa il numero di tick ProgressBar da aggiungere al conteggio totale durante la fase di acquisizione e generazione dello script dell'installazione.

Per aggiungere un'azione personalizzata a ProgressBar

  1. Decidere in che modo l'azione personalizzata descriverà lo stato di avanzamento. Ad esempio, un'azione personalizzata che installa le chiavi del Registro di sistema potrebbe visualizzare un messaggio di stato e aggiornare ProgressBar ogni volta che il programma di installazione scrive una chiave del Registro di sistema.

  2. Ogni aggiornamento da parte dell'azione personalizzata modifica la lunghezza di ProgressBar in base a un incremento costante. Specificare o calcolare il numero di tick in ogni incremento. In genere, una modifica della lunghezza di ProgressBar di un segno di graduazione corrisponde all'installazione di un byte. Ad esempio, se il programma di installazione installa circa 10000 byte quando scrive una chiave del Registro di sistema, è possibile specificare che sono presenti 10000 tick in un incremento.

  3. Specificare o calcolare il numero totale di tick che l'azione personalizzata aggiunge alla lunghezza di ProgressBar. Il numero di tick aggiunti dall'azione personalizzata viene in genere calcolato come: (incremento tick) x (numero di elementi). Ad esempio, se l'azione personalizzata scrive 10 chiavi del Registro di sistema, il programma di installazione installa circa 100000 byte e il programma di installazione deve quindi aumentare la stima della lunghezza totale finale di ProgressBar di 10000 tick.

    Nota

    Per calcolare questa operazione in modo dinamico, l'azione personalizzata deve contenere una sezione che viene eseguita immediatamente durante la generazione di script. La quantità di tick segnalata dall'azione personalizzata di esecuzione posticipata deve essere uguale al numero di tick aggiunti al numero totale di tick dall'azione di esecuzione immediata. In caso contrario, il tempo rimanente come segnalato dal controllo di testo TimeRemaining non sarà accurato.

     

  4. Separare l'azione personalizzata in due sezioni di codice: una sezione eseguita durante la fase di generazione dello script e una sezione eseguita durante la fase di esecuzione dell'installazione. È possibile eseguire questa operazione usando due file oppure è possibile usare un file condizionando la modalità di esecuzione del programma di installazione. Nell'esempio seguente viene usato un file e viene controllato lo stato di installazione. Le sezioni dell'esempio vengono condizionali per l'esecuzione a seconda che il programma di installazione si trovi nella fase di esecuzione o generazione di script dell'installazione.

  5. La sezione eseguita durante la generazione di script deve aumentare la stima della lunghezza totale finale di ProgressBar in base al numero totale di tick nell'azione personalizzata. A tale scopo, inviare un messaggio di stato ProgressAddition .

  6. La sezione eseguita durante la fase di esecuzione dell'installazione deve configurare il testo del messaggio e i modelli per informare l'utente dell'azione personalizzata e di indirizzare il programma di installazione all'aggiornamento del controllo ProgressBar . Ad esempio, informare il programma di installazione di spostare progressBar avanti un incremento e inviare un messaggio di stato esplicito con ogni aggiornamento. In genere in questa sezione è presente un ciclo se l'azione personalizzata sta installando un elemento. Con ogni passaggio di questo ciclo, il programma di installazione può installare un elemento di riferimento, ad esempio una chiave del Registro di sistema e aggiornare il controllo ProgressBar

  7. Aggiungere un'azione personalizzata di esecuzione immediata al pacchetto di Windows Installer. Questa azione personalizzata indica a ProgressBar quanto avanzare durante le fasi di acquisizione e generazione di script dell'installazione. Per l'esempio seguente, l'origine è la DLL creata compilando il codice di esempio e la destinazione è il punto di ingresso, CAProgress.

  8. Aggiungere un'azione personalizzata di esecuzione posticipata al pacchetto di Windows Installer. Questa azione personalizzata completa i passaggi dell'installazione effettiva e informa ProgressBar quanto avanzare la barra nel momento in cui il programma di installazione esegue lo script di installazione. Per l'esempio seguente, l'origine è la DLL creata compilando il codice di esempio e la destinazione è il punto di ingresso, CAProgress.

  9. Pianificare entrambe le azioni personalizzate tra InstallInitialize e InstallFinalize nella tabella InstallExecuteSequence . L'azione personalizzata posticipata deve essere pianificata immediatamente dopo l'azione personalizzata di esecuzione immediata. Il programma di installazione non eseguirà l'azione personalizzata posticipata fino a quando non viene eseguito lo script.

Nell'esempio seguente viene illustrato come aggiungere un'azione personalizzata a ProgressBar. L'origine di entrambe le azioni personalizzate è la DLL creata compilando il codice di esempio e la destinazione di entrambe le azioni personalizzate è il punto di ingresso, CAProgress. In questo esempio non vengono apportate modifiche effettive al sistema, ma viene usato ProgressBar come se si installassero 10 elementi di riferimento ciascuno di circa 10.000 byte. Il programma di installazione aggiorna il messaggio e ProgressBar ogni volta che installa un elemento di riferimento.

#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;
     }
}