本文介绍了Windows API - ShellExecuteEx() 没有等待 USB 驱动器和 CD 驱动器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个主安装程序,其中包含以下 ShellExecuteEx() 函数,该函数通过循环构造一个接一个调用一些高级安装程序创建的安装程序(安装多个产品).

I am writing a master installer with the following ShellExecuteEx() function that call a few Advanced Installer created installers (installing multiple products) one by one through a loop construct.

// Shell Execute
bool CFileHelper::ShellExecute(CString strCommandPath, CString strOptions)
{

    CString strQCommandPath = CString(_T("\"")) + strCommandPath +  CString(_T("\""));  //place the command in the quote to handle path with space

    LPWSTR szInstallerPath = strQCommandPath.GetBuffer();
    LPWSTR szOptions = strOptions.GetBuffer(MAX_PATH);

    SHELLEXECUTEINFO ShellInfo; // Name structure

    memset(&ShellInfo, 0, sizeof(ShellInfo)); // Set up memory block
    ShellInfo.cbSize = sizeof(ShellInfo); // Set up structure size
    ShellInfo.hwnd = 0; // Calling window handle
    ShellInfo.lpVerb = _T("open");
    ShellInfo.lpFile = szInstallerPath;
    ShellInfo.fMask = SEE_MASK_NOCLOSEPROCESS; //| SEE_MASK_NOASYNC | SEE_MASK_WAITFORINPUTIDLE;
    ShellInfo.lpParameters = szOptions;
    bool res = ShellExecuteEx(&ShellInfo); // Call to function
    if (!res)
    {
        //printf( "CreateProcess failed (%d).\n", GetLastError() );
        CString strMsg = CString(_T("Failed to execute command ")) + strCommandPath +  CString(_T("!"));
        AfxMessageBox(strMsg);
        return false;
    }

    WaitForSingleObject(ShellInfo.hProcess, INFINITE); // wait forever for process to finish
    //WaitForInputIdle(ShellInfo.hProcess, INFINITE);

    CloseHandle( ShellInfo.hProcess);

    strQCommandPath.ReleaseBuffer();
    strOptions.ReleaseBuffer();
    return true;
}

当我在硬盘驱动器上安装此主安装程序和其他单个产品安装程序时,该功能运行良好.

The function work every well when I have this master installer and other individual product installers on hard drive.

但是,如果我将它们全部移动到 USB 驱动器或 CD,ShellExecuteEx() 不会等待先前的产品安装程序完成其任务.因此,所有产品安装人员都可以立即享用午餐;给我错误消息正在进行另一个安装.您必须先完成该安装,然后才能继续安装.".

However, if I move all of them to either USB drive or CD, the ShellExecuteEx() didn't wait for the previous product installer to complete its task. So all product installers get lunched at once; giving me the error message "Another installation is in progress. You must complete that installation before continuing this one.".

让我感到困惑的是,为什么它可以在硬盘驱动器上运行,而不能在 USB 驱动器和 CD 驱动器上运行.我需要分发 CD 上的产品.

One thing puzzle me is why it works on hard drive but not on USB drive and CD drive. I need to distribute the products on CD.

将 Sleep(500) 置于 WaitForSingleObject(ShellInfo.hProcess, INFINITE) 之前也无济于事.

Putting Sleep(500) before WaitForSingleObject(ShellInfo.hProcess, INFINITE) didn't help as well.

推荐答案

假设这是真实的.安装程序可能已经注意到它是从可移动驱动器启动并将自身复制到硬盘上的.启动该副本并退出.这避免了用户弹出媒体时的麻烦,这会产生进程本身无法捕获的非常低级别的分页错误.Windows 对话框不是很好,很可能与安装程序插入下一张磁盘的请求背道而驰.

Work from the assumption that this is real. The installer might have noticed it was started from a removable drive and copied itself to the hard disk. Launched that copy and quit. This avoids trouble when the user pops out the media, that produces a very low-level paging fault that the process itself cannot catch. The Windows dialog isn't great and may well run counter to the installer's request to insert the next disk.

通过比较您启动的进程的进程 ID 与您在 Taskmgr.exe 中看到的运行的进程 ID 来验证这一猜测.可靠地解决这个问题应该很头疼.

Verify this guess by comparing the process ID of the process you started vs the one you see running in Taskmgr.exe. Reliably fixing this ought to be quite a headache.

这篇关于Windows API - ShellExecuteEx() 没有等待 USB 驱动器和 CD 驱动器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 14:58