Lägga till anpassade åtgärder i ProgressBar
Anpassade åtgärder kan lägga till tids- och förloppsinformation i en ProgressBar-kontroll. Mer information om hur du skapar en dialogruta för åtgärdsvisning med en ProgressBar finns i Authoring a ProgressBar Control.
Observera att två anpassade åtgärder måste läggas till i Windows Installer-paketet för att korrekt rapportera tids- och förloppsinformation till ProgressBar. En anpassad åtgärd måste vara en uppskjuten anpassad åtgärd. Den här anpassade åtgärden bör slutföra din anpassade installation och skicka antalet enskilda steg till ProgressBar- kontroll när installationsprogrammet kör installationsskriptet. Den andra anpassade åtgärden måste vara en omedelbart utförd anpassad åtgärd som informerar ProgressBar om hur många tick som ska läggas till det totala antalet under förvärvs- och skriptgenereringsfasen av installationen.
Om du vill lägga till en anpassad åtgärd i ProgressBar-
Bestäm hur den anpassade åtgärden ska beskriva dess förlopp. En anpassad åtgärd som installerar registernycklar kan till exempel visa ett förloppsmeddelande och uppdatera ProgressBar- varje gång installationsprogrammet skriver en registernyckel.
Varje uppdatering av den anpassade åtgärden ändrar längden på ProgressBar med ett konstant steg. Ange eller beräkna antalet tick i varje steg. Normalt motsvarar en ändring i ProgressBar-längden på en tick installationen av en byte. Om installationsprogrammet till exempel installerar cirka 1 0000 byte när det skriver en registernyckel kan du ange att det finns 1 000 tick i en ökning.
Ange eller beräkna det totala antalet tick som den anpassade åtgärden lägger till i längden på ProgressBar. Antalet tick som läggs till av den anpassade åtgärden beräknas vanligtvis som: (tick-ökning) x (antalet objekt). Om den anpassade åtgärden till exempel skriver 10 registernycklar installerar installationsprogrammet cirka 10 0000 byte och installationsprogrammet måste därför öka uppskattningen av den slutliga totala längden på ProgressBar med 100 000 tick.
Anteckning
Om du vill beräkna detta dynamiskt måste den anpassade åtgärden innehålla ett avsnitt som körs omedelbart under skriptgenereringen. Antalet ticks som rapporteras av den anpassade åtgärden för uppskjuten exekvering måste vara lika med antalet ticks som läggs till i det totala antalet ticks genom den omedelbara exekveringsåtgärden. Om så inte är fallet blir den tid som återstår enligt timeremaining-textkontrollen felaktig.
Avgränsa din anpassade åtgärd i två kodavsnitt: ett avsnitt som körs under skriptgenereringsfasen och ett avsnitt som körs under installationens körningsfas. Du kan göra detta med hjälp av två filer eller så kan du använda en fil genom att villkora installationsprogrammets körningsläge. I följande exempel används en fil och installationstillståndet kontrolleras. Avsnitt i exemplet villkoras att köras beroende på om installationsprogrammet är i körnings- eller skriptgenereringsfasen för installationen.
Avsnittet som körs under skriptgenereringen bör öka uppskattningen av den slutliga totala längden på ProgressBar med det totala antalet tick i den anpassade åtgärden. Detta görs genom att skicka ett ProgressAddition förloppsmeddelande.
Avsnittet som körs under installationens körningsfas bör konfigurera meddelandetext och mallar för att informera användaren om vad den anpassade åtgärden gör och för att dirigera installationsprogrammet om uppdatering av ProgressBar- kontroll. Informera installationsprogrammet, till exempel, att flytta ProgressBar framåt ett steg och skicka ett explicit förloppsmeddelande med varje uppdatering. Det finns vanligtvis en loop i det här avsnittet om den anpassade åtgärden installerar något. Med varje genomströmning av den här loopen kan installationsprogrammet installera ett referensobjekt, till exempel en registernyckel, och uppdatera ProgressBar-kontrollen
Lägg till en anpassad åtgärd för omedelbar körning i ditt Windows Installer-paket. Den här anpassade åtgärden informerar ProgressBar hur mycket den ska avancera under förvärv och skriptgenereringsfaserna av installationen. För följande exempel är källan den DLL som skapas genom att kompilera exempelkoden och målet är startpunkten CAProgress.
Lägg till en anpassad åtgärd för uppskjuten körning i ditt Windows Installer-paket. Den här anpassade åtgärden slutför stegen i den faktiska installationen och informerar ProgressBar hur mycket du kan föra fältet framåt vid den tidpunkt då installationsprogrammet kör installationsskriptet. För följande exempel är källan den DLL som skapas genom att kompilera exempelkoden och målet är startpunkten CAProgress.
Schemalägg båda anpassade åtgärderna mellan InstallInitialize och InstallFinalize i tabellen InstallExecuteSequence. Den uppskjutna anpassade åtgärden bör schemaläggas omedelbart efter den omedelbara anpassade åtgärden. Installationsprogrammet kör inte den uppskjutna anpassade åtgärden förrän skriptet körs.
Följande exempel visar hur en anpassad åtgärd kan läggas till i ProgressBar. Källan till båda anpassade åtgärderna är den DLL som skapas genom att kompilera exempelkoden och målet för båda anpassade åtgärderna är startpunkten, CAProgress. Det här exemplet gör inga faktiska ändringar i systemet, men kör ProgressBar som om du installerar 10 referensobjekt som var och en är ungefär 10 000 byte stora. Installationsprogrammet uppdaterar meddelandet och ProgressBar varje gång det installerar ett referensobjekt.
#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;
}
}