Condividi tramite


Aggiunta di azioni personalizzate a ProgressBar

Azioni personalizzate è possibile 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 di un'azione con progressBar, vedere Creazione di un controllo ProgressBar.

Si noti che è necessario aggiungere due azioni personalizzate 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 i 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 progressBar il numero di tick da aggiungere al conteggio totale durante la fase di acquisizione e generazione di script dell'installazione.

Per aggiungere un'azione personalizzata al 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 il ProgressBar ogni volta che il programma di installazione scrive una chiave del Registro di sistema.

  2. Ogni aggiornamento dell'azione personalizzata modifica la lunghezza della barra di avanzamento ProgressBar con un incremento costante. Specificare o calcolare il numero di tick in ogni incremento. In genere, una modifica nella lunghezza di ProgressBar di un tick 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 aggiunti dall'azione personalizzata alla lunghezza del ProgressBar. Il numero di tick aggiunti dall'azione personalizzata è generalmente calcolato come: (incremento del 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 questo risultato in modo dinamico, l'azione personalizzata deve contenere una sezione che viene eseguita immediatamente durante la generazione di script. La quantità di tick segnalati dall'azione personalizzata per l'esecuzione posticipata deve essere uguale al numero di tick aggiunti al conteggio totale dei tick dall'azione di esecuzione immediata. In caso contrario, il tempo rimanente come indicato dall'elemento di controllo testuale 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 solo file condizionando la modalità di esecuzione del programma di installazione. L'esempio seguente usa un file e controlla lo stato di installazione. Le sezioni dell'esempio sono condizionate a eseguire in base al fatto che il programma di installazione si trovi nella fase di esecuzione o nella fase di generazione degli script durante l'installazione.

  5. La sezione eseguita durante la generazione di script deve aumentare la stima della lunghezza totale finale del ProgressBar in base al numero totale di tick nell'azione personalizzata. Questo avviene inviando 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 indirizzare il programma di installazione all'aggiornamento del controllo ProgressBar. Ad esempio, informa l'installatore di avanzare la ProgressBar di un incremento e mandare un messaggio di progressi esplicito con ogni aggiornamento. In genere è presente un ciclo in questa sezione se l'azione personalizzata sta installando qualcosa. 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 informa il 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 le fasi dell'effettiva installazione e comunica al ProgressBar di quanto avanzare la barra nel momento in cui il programma di installazione esegue lo script d'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 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 al 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;
     }
}