【问题标题】:How to emulate ShellExecute() with CreateProcess()如何用 CreateProcess() 模拟 ShellExecute()
【发布时间】:2019-07-14 13:59:45
【问题描述】:

我正在尝试使用CreateProcess() 打开一个*.jpg 文件,并且我希望CreateProcess() 的行为与使用ShellExecute() 打开*.jpg 时的行为完全相同。 p>

所以我首先使用FindExecutable() 来获取*.jpg 文件的查看器应用程序,然后我连接查看器应用程序的路径和*.jpg 文件的路径,添加引号以确保它适用于具有其中的空格。

但是,结果不一样:在我的系统上,*.jpg 文件与具有轻量级查看器模式和更复杂的编辑器模式的应用程序相关联。当我使用ShellExecute() 打开文件(或在资源管理器中双击它)时,查看器应用程序以轻量级查看器模式打开。但是,当我如上所述使用CreateProcess() 时,查看器应用程序也会显示*.jpg 文件,但它会以编辑器模式打开。

所以ShellExecute() 一定是在做其他事情,导致查看器应用程序的行为与它一样,但我不知道是什么。使CreateProcess() 的行为与ShellExecute() 完全相同可能缺少什么想法?

这是当前代码的样子:

PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;

memset(&piProcInfo, 0, sizeof(PROCESS_INFORMATION));
memset(&siStartInfo, 0, sizeof(STARTUPINFO));

siStartInfo.cb = sizeof(STARTUPINFO); 

CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &piProcInfo);

【问题讨论】:

  • ShellExecute 托管 几十年 的兼容性垫片。试图准确地复制它的行为要么几乎是不可能的,要么是不合法的。
  • 我什至可能不需要完全复制它的行为,我只是想知道为什么查看器应用程序会这样,以及是否有办法让它的行为就像文件是通过 ShellExecute() 启动的一样.
  • “我希望CreateProcess() 的行为完全与使用ShellExecute() 打开*.jpg 时的行为相同。” - 如果你不这样做不想这样,不要要求。无论如何,如果ShellExecute 有一个内部应用程序列表来决定最合适的应用程序,我不会太惊讶,因为应用程序匹配同样合适。
  • 为什么不能使用ShellExecute/ShellExecuteEx?您要解决的实际问题是什么?
  • @zet:不使用ShellExecute[Ex] 的一个原因是,如果您从一个初始化为多线程单元的线程调用它。当然,这可以通过在问题上抛出另一个线程来解决,但这可能不可行。

标签: winapi


【解决方案1】:

ShellExecute 在内部使用CreateProcess,但在它到达之前它会做许多其他事情。

Raymond Chen 的This blog post 提供了一个提示:

FindExecutable 函数来自 16 位 Windows,在那个年代,没有上下文菜单外壳扩展或自定义放置目标。 (有 DDE,但没关系,因为程序仍然必须注册一个可执行文件才能在没有人响应 DDE 消息时的备用情况下使用。)

...

无论如何,较新的应用程序不应该使用 FindExecutable,因为文件类型的处理程序甚至可能不是可执行文件。

基于IContextMenu 的shell 扩展可能是默认的,如果是,它可以做任何事情,ShellExecute 只是告诉扩展调用命令。如果没有指定SEE_MASK_INVOKEIDLIST,这不做吗?

注册表中的经典静态动词可以有IExecuteCommand 和/或删除也执行实际执行的目标处理程序。

如果以上都不成立,ShellExecute 将寻找 DDE 注册,如果找到,它将尝试使用 DDE。

如果所有其他方法都失败,ShellExecute 将在替换 %1 值后使用 CreateProcess 调用命令字符串。

即使您模拟所有这些(包括所有未记录的详细信息和兼容性变通办法),如果命令解析为需要 UAC 提升的可执行文件,您仍然必须调用 ShellExecute

仅仅弄清楚哪个动词是真正的默认值就够难了,我建议你只使用ShellExecute,让shell处理剩下的事情。

如果您只是好奇,可以在任务管理器或进程资源管理器中查看生成的命令行,看看自定义处理程序是否只是添加了一个特殊参数。

【讨论】:

    猜你喜欢
    • 2012-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 1970-01-01
    • 2012-08-03
    相关资源
    最近更新 更多