2

次のコードを使用して、CustomBA の単一インスタンスが CustomBA の Run ブロックで既に実行されているかどうかを確認します。

ユーザーが「setup.exe」(CustomBA) をダブルクリックして起動すると、以下のコードは期待どおりの動作である true を返します。

ただし、ユーザーが右クリックして管理者として起動すると、コードは false を返します。何故ですか?

private bool IsSingleInstanceOfSetupRunning()
{
    bool result = true;

    Process currentProcess = Process.GetCurrentProcess();
    if (Process.GetProcessesByName(currentProcess.ProcessName).Length > 1)
    {
        result = false;
    }

    return result;
}
4

1 に答える 1

3

WiX エンジンは、プロセスが管理者として実行されていることを検出し、MSI を実際にインストールするために使用されるセカンダリ プロセスを起動しているようです。したがって、実際には同じ名前で実行されている 2 つのプロセスがあります。

CustomBA コードが Engine.Apply() を呼び出すと、非管理プロセスで同じ動作を確認できます。これは通常、エンジンが実際の MSI インストールを処理するために昇格された 2 番目のプロセスをスピンアップするときに、ユーザーに UAC プロンプトが表示される場合です。

メイン プロセスはすでに管理者として実行されており、2 番目のプロセスを起動しても UAC プロンプトは表示されないため、Engine は先に進み、Engine.Apply() の呼び出しを待つ代わりにすぐに開始します。

また、注意: メジャー アップグレードを実行している場合、アップグレード中に以前のバージョンのアンインストールが (サイレント モードで) 実行されるため、追加のプロセスが必要になります。別のプロセス (アップグレード プロセス) が既に実行されている場合でも、アンインストール プロセスの実行を許可する必要があります。

1 つのアプローチは、ミューテックスを使用してチェックを行うことですが、DisplayMode Display.Full で実行している場合のみです。

if (DisplayMode == Display.Full)
{
    bool mutexCreated = false;
    mutex = new Mutex(true, @"My Installer F1096BB9-CFDF-4AD1-91D8-9AA8805784A8", out mutexCreated);
    if (!mutexCreated)
    {
        MessageBox.Show("Another instance of the installer is already running. You may only run one at a time.",
                        "Installer already running", MessageBoxButton.OK,
                        MessageBoxImage.Warning);
        Log("Installer already running");
        Exit(ActionResult.NotExecuted);
    }
}

public void Exit(ActionResult actionResult)
{

    if (mutex != null)
    {
        mutex.Close();
        mutex = null;
    }

    Log(string.Format("Exiting with code {0}", actionResult));
    Engine.Quit((int) actionResult);    
}
于 2013-10-23T13:37:28.857 に答える