WiX自定义引导程序 - 单实例检查

时间:2013-10-21 15:17:36

标签: wix administrator wix3.7 burn

我使用以下代码检查CustomBA的Single实例是否已在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;
}

1 个答案:

答案 0 :(得分:3)

WiX引擎似乎检测到该进程正在以管理员身份运行,并且会旋转用于实际安装MSI的辅助进程。所以实际上有两个进程以相同的名称运行。

一旦您的CustomBA代码调用Engine.Apply(),您就可以看到与非管理进程相同的行为。这通常是当用户看到UAC提示时,引擎会旋转第二个提升的进程来处理实际的MSI安装。

由于主进程已经作为管理员运行,并且通过启动第二个进程不会发生UAC提示,引擎会继续并立即启动它,而不是等待对Engine.Apply()的调用。

另请注意:如果您正在执行主要升级,则在升级期间将运行先前版本的卸载(以静默模式),这将导致其他进程。即使已经有另一个进程在运行(升级过程),您也需要确保允许卸载过程运行。

一种方法是使用互斥锁进行检查,但仅限于在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);    
}