Adicionando ações personalizadas à ProgressBar
As Ações Personalizadas podem adicionar informações de tempo e progresso a ProgressBar. Para obter mais informações sobre como criar uma caixa de diálogo de exibição de ação com uma ProgressBar, consulte Criação de um controle ProgressBar.
Observe que duas ações personalizadas devem ser adicionadas ao pacote do Windows Installer para relatar com precisão informações de tempo e progresso para a ProgressBar. Uma ação personalizada tem de ser adiada. Esta ação personalizada deve finalizar a instalação personalizada e enviar as quantidades dos incrementos individuais para o controlo de Barra de Progresso quando o instalador executar o script de instalação. A segunda ação personalizada deve ser uma ação personalizada de execução imediata que informa à ProgressBar quantos ticks adicionar à contagem total durante a fase de aquisição e geração de script da instalação.
Para adicionar uma ação personalizada ao ProgressBar
Decida como a ação personalizada descreverá seu progresso. Por exemplo, uma ação personalizada que instala chaves do Registro pode exibir uma mensagem de progresso e atualizar a ProgressBar cada vez que o instalador grava uma chave do Registro.
Cada atualização pela ação personalizada altera o comprimento do ProgressBar por um incremento constante. Especifique ou calcule o número de ticks em cada incremento. Normalmente, uma alteração no comprimento da ProgressBar de um tick corresponde à instalação de um byte. Por exemplo, se o instalador instala aproximadamente 10000 bytes quando grava uma chave do Registro, você pode especificar que há 10000 ticks em um incremento.
Especifique ou calcule o número total de ticks que a ação personalizada adiciona ao comprimento do ProgressBar. O número de ticks adicionados pela ação personalizada é geralmente calculado da seguinte forma: (incremento de ticks) x (número de itens). Por exemplo, se a ação personalizada grava 10 chaves do Registro, o instalador instala aproximadamente 100000 bytes e, portanto, o instalador deve aumentar a estimativa do comprimento total final da ProgressBar em 100000 ticks.
Observação
Para calcular isso dinamicamente, a ação personalizada deve conter uma seção que é executada imediatamente durante a geração de script. A quantidade de ticks relatados pela sua ação personalizada de execução adiada deve ser igual ao número de ticks adicionados à contagem total de ticks pela ação de execução imediata. Se esse não for o caso, o tempo restante conforme relatado pelo controle de texto TimeRemaining será impreciso.
Separe sua ação personalizada em duas seções de código: uma seção que é executada durante a fase de geração de script e uma seção que é executada durante a fase de execução da instalação. Você pode fazer isso usando dois arquivos ou você pode usar um arquivo condicionando no modo de execução do instalador. O exemplo a seguir usa um arquivo e verifica o estado da instalação. As seções do exemplo são condicionadas a serem executadas dependendo se o instalador está na fase de execução ou geração de script da instalação.
A seção que é executada durante a geração do script deve aumentar a estimativa do comprimento total final do ProgressBar pelo número total de ticks na ação personalizada. Isso é feito enviando uma ProgressAddition mensagem de progresso.
A seção que é executada durante a fase de execução da instalação deve configurar o texto da mensagem e os modelos para informar o utilizador sobre o que a ação personalizada está a fazer e orientar o instalador na atualização do controlo ProgressBar. Por exemplo, informe o instalador para mover a ProgressBar um incremento para a frente e enviar uma mensagem de progresso explícita a cada atualização. Normalmente, há um loop nesta seção se a ação personalizada estiver instalando algo. Com cada passagem por esse loop, o instalador pode instalar um item de referência, como uma chave do Registro e atualizar o controle ProgressBar
Adicione uma ação personalizada de execução imediata ao seu pacote do Windows Installer. Esta ação customizada informa o ProgressBar quanto avançar durante as fases de aquisição e geração de scripts da instalação. Para o exemplo a seguir, a fonte é a DLL criada compilando o código de exemplo e o destino é o ponto de entrada, CAProgress.
Adicione uma ação personalizada de execução adiada ao seu pacote do Windows Installer. Esta ação personalizada conclui as etapas da instalação propriamente dita e informa o ProgressBar quanto avançar a barra no momento em que o instalador executa o script de instalação. Para o exemplo a seguir, a fonte é a DLL criada compilando o código de exemplo e o destino é o ponto de entrada, CAProgress.
Agende ambas as ações personalizadas entre InstallInitialize e InstallFinalize na tabela InstallExecuteSequence. A ação personalizada adiada deve ser agendada imediatamente após a ação personalizada de execução imediata. O instalador não executará a ação personalizada adiada até que o script seja executado.
O exemplo a seguir mostra como uma ação personalizada pode ser adicionada ao ProgressBar. A origem de ambas as ações personalizadas é a DLL criada compilando o código de exemplo e o destino de ambas as ações personalizadas é o ponto de entrada, CAProgress. Este exemplo não faz nenhuma alteração real no sistema, mas opera a ProgressBar como se instalasse 10 itens de referência cada um com aproximadamente 10.000 bytes de tamanho. O instalador atualiza a mensagem e ProgressBar cada vez que instala um item de referência.
#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;
}
}