为啥 ShellExecuteEx 不返回进程句柄?

Posted

技术标签:

【中文标题】为啥 ShellExecuteEx 不返回进程句柄?【英文标题】:Why is ShellExecuteEx not returning the process handle?为什么 ShellExecuteEx 不返回进程句柄? 【发布时间】:2013-12-02 02:17:58 【问题描述】:

我正在尝试使用以下功能打开图像:

HANDLE openFile(char *path) // path = "C:\Users\Foo Bar\Code\Test\test.jpg"
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

    SHELLEXECUTEINFOW info;
    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NOASYNC ;
    info.hwnd = NULL;
    info.lpVerb = L"open";
    info.lpFile = utf8_toWchar(path);
    info.lpParameters = NULL;
    info.lpDirectory = NULL;
    info.nShow = SW_SHOW;
    info.hInstApp = NULL;

    if (!ShellExecuteExW(&info))
        System_printLastErrorString(); //never gets here
    
    //free((void*)info.lpFile);
    CoUninitialize();

    return info.hProcess; //this is always NULL

问题在于info.hProcess 始终是NULL,尽管默认图像编辑程序未打开并且稍后打开。

我该如何解决这个问题?

旁注:我不知道这是否相关,但调用程序是 Qt 应用程序。

【问题讨论】:

并非所有执行都会导致进程的创建。例如,inproc 激活在您的进程中运行。 @RaymondChen 这显然不是在这种情况下发生的事情,因为几秒钟后会产生一个进程。 进程不是由 ShellExecute 创建的。 (看起来它是在 ShellExecute 已经返回之后创建的,并且 ShellExecute 不是通灵的。) @RaymondChen 不......但我认为它只是以异步方式创建它,尽管有标志,问题是为什么。 启动了什么进程?标准图片查看器应用程序在进程内运行。 【参考方案1】:

我最终自己调用了CreateProcess 来获取AssocQueryString 的结果。这给了我所需的句柄。

【讨论】:

以上是关于为啥 ShellExecuteEx 不返回进程句柄?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用从父级继承的句柄创建提升的子进程

将 unicode 参数传递给 ShellExecuteEx 中的子进程

ShellExecuteEx 阻塞和异步调用进程的两种方法

ShellExecute的返回值是进程的句柄吗

等待由 IShellDispatch2.ShellExecute 启动的进程

ShellExecuteEx 并等待文件实际打开