Hinzufügen benutzerdefinierter Aktionen zur Statusleiste (ProgressBar)

Benutzerdefinierte Aktionen können einem ProgressBar-Steuerelement Zeit- und Fortschrittsinformationen hinzufügen. Weitere Informationen zum Erstellen eines Aktionsanzeige-Dialogfelds mit einer Statusleiste finden Sie unter Erstellen eines ProgressBar-Steuerelements.

Beachten Sie, dass dem Windows Installer-Paket zwei benutzerdefinierte Aktionen hinzugefügt werden müssen, um Zeit- und Fortschrittsinformationen exakt an das ProgressBar-Steuerelement zu melden. Eine benutzerdefinierte Aktion muss eine verzögerte benutzerdefinierte Aktion sein. Diese benutzerdefinierte Aktion sollte Ihre benutzerdefinierte Installation abschließen und die Mengen der einzelnen Inkremente an das ProgressBar-Steuerelement senden, wenn das Installationsprogramm das Installationsskript ausführt. Die zweite benutzerdefinierte Aktion muss eine sofort auszuführende benutzerdefinierte Aktion sein, die das ProgressBar-Steuerelement darüber informiert, wie viele Teilstriche während der Erfassungs- und Skriptgenerierungsphase der Installation der Gesamtzahl hinzugefügt werden sollen.

So fügen Sie dem ProgressBar-Steuerelement eine benutzerdefinierte Aktion hinzu

  1. Entscheiden Sie, wie die benutzerdefinierte Aktion ihren Fortschritt beschreibt. Beispielsweise kann eine benutzerdefinierte Aktion, die Registrierungsschlüssel installiert, eine Statusmeldung anzeigen und das ProgressBar-Steuerelement jedes Mal aktualisieren, wenn das Installationsprogramm einen Registrierungsschlüssel schreibt.

  2. Jede Aktualisierung durch die benutzerdefinierte Aktion ändert die Länge des ProgressBar-Steuerelements um einen konstanten Inkrementwert. Geben Sie die Anzahl der Teilstriche in jedem Inkrement an, oder berechnen Sie diese. In der Regel entspricht eine Änderung der Länge des ProgressBar-Steuerelements von einem Teilstrich der Installation eines Bytes. Wenn das Installationsprogramm beispielsweise etwa 10.000 Bytes installiert, wenn es einen Registrierungsschlüssel schreibt, können Sie angeben, dass in einem Inkrement 10.000 Teilstriche enthalten sind.

  3. Geben Sie die Gesamtzahl der Teilstriche an, die die benutzerdefinierte Aktion der Länge des ProgressBar-Steuerelements hinzufügt, oder berechnen Sie diese. Die Anzahl der durch die benutzerdefinierte Aktion hinzugefügten Teilstriche wird normalerweise wie folgt berechnet: (Teilstrichinkrement) x (Anzahl der Elemente). Wenn die benutzerdefinierte Aktion beispielsweise 10 Registrierungsschlüssel schreibt, installiert das Installationsprogramm ungefähr 10.000 Bytes, weshalb das Installationsprogramm die Schätzung der endgültigen Gesamtlänge des ProgressBar-Steuerelements um 100.000 Teilstriche erhöhen muss.

    Hinweis

    Um dies dynamisch zu berechnen, muss die benutzerdefinierte Aktion einen Abschnitt enthalten, der während der Skriptgenerierung sofort ausgeführt wird. Die Anzahl der von Ihrer verzögert auszuführenden benutzerdefinierten Aktion gemeldeten Teilstriche muss der Anzahl von Teilstrichen entsprechen, die der Gesamtzahl der Teilstriche durch die sofort auszuführende Aktion hinzugefügt wurden. Wenn dies nicht der Fall ist, ist die verbleibende Zeit, die vom TimeRemaining-Textsteuerelement gemeldet wird, ungenau.

     

  4. Teilen Sie Ihre benutzerdefinierte Aktion in zwei Codeabschnitte auf: einen Abschnitt, der während der Skriptgenerierungsphase ausgeführt wird, und einen Abschnitt, der während der Ausführungsphase der Installation ausgeführt wird. Dazu können Sie zwei Dateien verwenden, oder Sie können eine Datei verwenden, indem Sie diese auf den Ausführungsmodus des Installers konditionieren. Im folgenden Beispiel wird eine Datei verwendet, und der Installationszustand wird überprüft. Abschnitte des Beispiels sind so bedingt, dass sie ausgeführt werden, je nachdem, ob sich das Installationsprogramm in der Ausführungs- oder in der Skriptgenerierungsphase der Installation befindet.

  5. Der Abschnitt, der während der Skriptgenerierung ausgeführt wird, sollte die Schätzung der endgültigen Gesamtlänge des ProgressBar-Steuerelements um die Gesamtzahl der Teilstriche in der benutzerdefinierten Aktion erhöhen. Hierzu wird eine ProgressAddition-Statusmeldung gesendet.

  6. Der Abschnitt, der während der Ausführungsphase der Installation ausgeführt wird, sollte Nachrichtentext und Vorlagen einrichten, um den Benutzer darüber zu informieren, was die benutzerdefinierte Aktion macht, und um das Installationsprogramm anzuweisen, das ProgressBar-Steuerelement zu aktualisieren. Weisen Sie z. B. das Installationsprogramm an, das ProgressBar-Steuerelement um einen Inkrementwert voranzubewegen und bei jeder Aktualisierung eine explizite Statusmeldung zu senden. In diesem Abschnitt gibt es normalerweise eine Schleife, wenn die benutzerdefinierte Aktion etwas installiert. Bei jedem Durchlaufen dieser Schleife kann das Installationsprogramm ein Referenzelement wie einen Registrierungsschlüssel installieren und das ProgressBar-Steuerelement aktualisieren.

  7. Fügen Sie Ihrem Windows Installer-Paket eine sofort auszuführende benutzerdefinierte Aktion hinzu. Diese benutzerdefinierte Aktion informiert das ProgressBar-Steuerelement darüber, um wie viel es während der Erfassungs- und Skriptgenerierungsphase der Installation voranbewegt werden soll. Im folgenden Beispiel ist die Quelle die DLL, die durch Kompilieren des Beispielcodes erstellt wird, und das Ziel ist der Einstiegspunkt „CAProgress“.

  8. Fügen Sie Ihrem Windows Installer-Paket eine verzögert auszuführende benutzerdefinierte Aktion hinzu. Diese benutzerdefinierte Aktion schließt die Schritte der tatsächlichen Installation ab und informiert das ProgressBar-Steuerelement darüber, um wie viel die Leiste zum Zeitpunkt der Ausführung des Installationsskripts durch das Installationsprogramm voranbewegt werden soll. Im folgenden Beispiel ist die Quelle die DLL, die durch Kompilieren des Beispielcodes erstellt wird, und das Ziel ist der Einstiegspunkt „CAProgress“.

  9. Planen Sie beide benutzerdefinierten Aktionen zwischen InstallInitialize und InstallFinalize in der Tabelle InstallExecuteSequence . Die verzögerte benutzerdefinierte Aktion sollte unmittelbar nach der sofort auszuführenden benutzerdefinierten Aktion geplant werden. Das Installationsprogramm führt die verzögerte benutzerdefinierte Aktion erst aus, wenn das Skript ausgeführt wird.

Das folgende Beispiel zeigt, wie dem ProgressBar-Steuerelement eine benutzerdefinierte Aktion hinzugefügt werden kann. Die Quelle beider benutzerdefinierten Aktionen ist die DLL, die durch Kompilieren des Beispielcodes erstellt wird, und das Ziel beider benutzerdefinierten Aktionen ist der Einstiegspunkt „CAProgress“. In diesem Beispiel werden keine tatsächlichen Änderungen am System vorgenommen, aber das ProgressBar-Steuerelement wird so behandelt, als ob 10 Referenzelemente installiert würden, die jeweils etwa 10.000 Bytes groß sind. Das Installationsprogramm aktualisiert die Meldung und das ProgressBar-Steuerelement jedes Mal, wenn ein Referenzelement installiert wird.

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