0

完全に無人の約20のインストールをキューに入れる必要があります(C#winformアプリケーションを使用)。各インストールには、(手動で作成された)独自のINIファイルがあり、各インストーラーがこの手順に必要な引数(そのプログラムが実行される前に読み込まれる)に関する適切な情報が含まれています。多くのアプリケーションで問題が発生しています。setup.exeを実行すると、プロセスがすぐに閉じてMSI(該当する場合)が起動し、最初のインストールが完了したと想定して、次のインストールで手順が実行されます。私はWebをスヌーピングする同様の問題を読みましたが、この問題に関する実際の解決策はありません...(MSIが完了するまでsetup.exeをメモリに保持する必要がある/ Waitオプション付きのバッチファイルを使用することを含むいくつかの回避策)。セットアップ。

このジレンマを解決するには、どのようなオプションが必要ですか?

手順を示すサンプルコードを次に示します。

            foreach (ListViewItem itm in this.lstSoftwares.Items)
            {
                try
                {
                    if (itm.Checked)
                    {
                        lblStatus.Text = "Status: Installing " + current.ToString() + " of " + count.ToString();

                        string InstallPath = Path.Combine(Application.StartupPath, "Software",
                        itm.Text, itm.Tag.ToString());

                        string CommandLine = itm.SubItems[1].Text;

                        Process process = new Process();
                        process.StartInfo.FileName = InstallPath;
                        process.StartInfo.Arguments = CommandLine;

                        process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
                        process.Start();
                        process.WaitForExit();
                        this.lstSoftwares.Items[i].SubItems[2].Text = "Complete";
                        current++;
                    }

アップデート

waitforexit()の直後に、msiexecが実行されているかどうかを確認するループを使用しています。

    private bool MSIRunning()
    {           
        try
        {
            using (var mutex = Mutex.OpenExisting(@"Global\_MSIExecute"))
            {                   
                return true;
            }

        }
        catch (Exception)
        {
            return false;
        }
    }

これは私の意見のハックですが、これまでのところトリックをやっています...

4

2 に答える 2

0

ループ内のprocess.startの後にMSIMutexをクエリすると(Mutexが3秒ごとに実行されているかどうかを確認し、戻っていない場合は次のインストールに進みます)、問題は解決したようです(上記のとおり)。

于 2013-02-28T15:47:09.267 に答える
0

すでに回答済みですが、MSIミューテックスチェックの実装が少し堅牢になっています。

public bool IsMsiExecFree(TimeSpan maxWaitTime)
{
    _logger.Info(@"Waiting up to {0}s for Global\_MSIExecute mutex to become free...", maxWaitTime.TotalSeconds);

    // The _MSIExecute mutex is used by the MSI installer service to serialize installations
    // and prevent multiple MSI based installations happening at the same time.
    // For more info: http://msdn.microsoft.com/en-us/library/aa372909(VS.85).aspx

    const string installerServiceMutexName = "Global\\_MSIExecute";
    Mutex msiExecuteMutex = null;
    var isMsiExecFree = false;

    try
    {
        msiExecuteMutex = Mutex.OpenExisting(installerServiceMutexName,
            MutexRights.Synchronize);
        isMsiExecFree = msiExecuteMutex.WaitOne(maxWaitTime, false);
    }
    catch (WaitHandleCannotBeOpenedException)
    {
        // Mutex doesn't exist, do nothing
        isMsiExecFree = true;
    }
    catch (ObjectDisposedException)
    {
        // Mutex was disposed between opening it and attempting to wait on it, do nothing
        isMsiExecFree = true;
    }
    finally
    {
        if (msiExecuteMutex != null && isMsiExecFree)
            msiExecuteMutex.ReleaseMutex();
    }

    _logger.Info(@"Global\_MSIExecute mutex is free, or {0}s has elapsed.", maxWaitTime.TotalSeconds);

    return isMsiExecFree;
}
于 2016-04-01T18:28:28.370 に答える