【问题标题】:Queuing installations via Process.Start通过 Process.Start 对安装进行排队
【发布时间】:2013-01-24 14:53:12
【问题描述】:

我需要对大约 20 个完全无人参与的安装进行排队(使用 C# winform 应用程序)。每个安装都有自己的 INI 文件(手动创建),其中包含有关每个安装程序为此过程需要哪些参数的正确信息(在执行该程序之前读入)。我遇到了许多应用程序的问题,当执行 setup.exe 时,进程立即关闭并启动其 MSI(如果适用),导致我的程序在下一次安装时执行,假设第一次安装已完成。我在网上阅读过类似的问题,但没有真正解决这个问题......(一些解决方法包括使用带有 /Wait 选项的批处理文件,它应该将 setup.exe 保留在内存中,直到其 MSI 完成)。 setup.exe 必须启动,因为它们包含引导程序。

我有什么办法来解决这个困境?

以下是一些演示该过程的示例代码:

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

在我看来,这是一个 hack,但目前为止还是在做这个伎俩......

【问题讨论】:

  • 你是怎么排队的?请发布一些代码,因为现在这个帖子太模糊了,需要详细信息。
  • 我把上面的代码贴上了,如果您需要任何其他信息,请告诉我
  • 您查看过 Process.ExitCode 以了解您获得的退出代码吗?
  • ExitCode 应该没问题。此行为是设计使然。尝试将 /w 添加到参数中。
  • 嗨 Ginosaji,经过我所有的研究,我明白这是设计使然...成为一种方法...我现在将尝试 /w 开关

标签: c# windows process windows-installer system.diagnostics


【解决方案1】:

在 process.start 之后在循环中查询 MSI Mutex(检查 Mutex 是否每 3 秒运行一次,如果没有返回并继续下一次安装)似乎可以解决问题(如上所述)。

【讨论】:

    【解决方案2】:

    已经回答,但我有一个更强大的 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;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-02-16
      • 2014-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多