6

Windows Installer 4.5 の新機能と WiX を使用してMSIパッケージを生成しています。

トランザクションとして他の MSI パッケージのコレクションをインストールするために、MSI チェーン インストールを作成しました。各パッケージは新しい組み込み UIオプションを使用しているため、UI をWPFにすることができます。ここまではすべて正常に動作します。

目標の 1 つを除いて、すべてのインストールに共通の進行状況バーを表示することです。現時点では、チェーン インストーラーにプログレス バーがありますが、これは他のパッケージが実行を開始する前に 100% に達します。

Fun with MsiEmbeddedChainerという投稿を読んだことがあります。しかし、私はそれを機能させることができません。もう少し詳しい説明と、いくつかのコード サンプルが欲しいです。

4

1 に答える 1

5

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

明らかに、各サブインストーラーはメインインストーラーに進行状況を通知できる必要があるため、製品全体でより広範な変更が必要になる可能性があります。それが努力に値するかどうかはあなた次第です。

于 2009-04-29T17:10:57.407 に答える