Установите цепочку встроенных пакетов MSI, каждый из которых использует встроенный пользовательский интерфейс - отображать общий индикатор выполнения - PullRequest
6 голосов
/ 30 сентября 2008

Я использую новые функции установщика Windows 4.5 и WiX для создания MSI пакетов.

Я создал цепочку MSI для установки коллекции других пакетов MSI в качестве транзакции. Каждый пакет использует новую опцию Embedded UI , поэтому пользовательский интерфейс может быть WPF . Пока все работает нормально.

За исключением одной из целей, будет отображаться общая шкала прогресса для всех установок. На данный момент у меня есть индикатор выполнения в установщике цепочки, но он достигает 100%, прежде чем другие пакеты начнут работать.

Я прочитал пост, Веселье с MsiEmbeddedChainer , в котором говорится, что то, что я хочу, может быть достигнуто. Но я не могу заставить его работать. Я хотел бы получить более подробные объяснения и, возможно, несколько примеров кода.

1 Ответ

5 голосов
/ 29 апреля 2009

Вы можете вручную контролировать состояние индикатора выполнения, отправляя сообщения INSTALLMESSAGE_PROGRESS установщику. Подробности можно найти здесь:

http://msdn.microsoft.com/en-us/library/aa370354.aspx

В частности, вам понадобится настраиваемое действие для управления строкой состояния (именно оно будет отвечать за соответствующие вызовы MsiProcessMessage. Я рекомендую также использовать его для вызова субинсталляторов. Здесь какой-то псевдокод для иллюстрации того, что я имею в виду:

LONG LaunchSubinstallersCA(MSIHANDLE current_installer)
{
    // Initialize the progress bar range and position
    MsiProcessMessage(current_installer, reset_message); // see MSDN for details

    for each (subinstaller in list_of_installers)
    {
        launch subinstaller;  // see MSDN for details

        // Update the progress bar to reflect most recent changes
        MsiProcessMessage(current_installer, increment_message); // see MSDN for details
    }

    return (result);
}

Основным недостатком является то, что индикатор выполнения будет работать несколько изменчиво. Если вы действительно хотите получить фантазию и сделать ее более плавной, вы можете запустить отдельный поток «слушателя», который будет ждать обновлений от субинсталлятора, чтобы сделать более мелкие приращения в индикатор выполнения. Что-то вроде:

LONG LaunchSubinstallersCA(MSIHANDLE current_installer)
{
    // Initialize the progress bar range and position
    MsiProcessMessage(current_installer, reset_message); // see MSDN for details

    launch_listener_thread();  // launches listener_thread_proc (see below)

    for each (subinstaller in list_of_installers)
    {
        launch subinstaller;  // see MSDN for details
    }

    tell_listener_thread_to_stop();
    optionally_wait_for_listener_thread_to_die();

    return (result);
}

void listener_thread_proc()
{
    // Loop until told to stop
    while (!time_for_me_to_stop)
    {
        // Listen for update from sub-installer
        timed_wait_for_update();  // probably required IPC, perhaps a named event?

        // Only update the progress bar if an update message was actually received
        if (!timeout)
        {
            // Update the progress bar to reflect most recent changes
            MsiProcessMessage(current_installer, increment_message); // see MSDN for details
        }
    }
}

Очевидно, что каждый вспомогательный установщик должен будет сигнализировать основному установщику, что достигнут прогресс, поэтому это может потребовать более обширных изменений в вашем продукте. Стоит ли это усилий или нет, решать только вам.

...