如何使用CreateProcess()模拟ShellExecute()

时间:2019-07-14 13:59:45

标签: winapi

我正在尝试使用*.jpg打开CreateProcess()文件,并且希望CreateProcess()的行为完全与打开{{1} }和*.jpg

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

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

因此*.jpg必须做一些其他事情,以使查看器应用程序表现出与它相同的行为,但是我不知道是什么。有什么想法可能会让ShellExecute()表现得与CreateProcess()完全一样?

这是当前代码的样子:

ShellExecute()

1 个答案:

答案 0 :(得分:3)

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

Raymond Chen的

This blog post提供了一个提示:

  

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

     

...

     

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

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

注册表中的经典静态动词可以具有IExecuteCommand和/或放置目标处理程序,它们也可以执行实际执行。

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

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

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

仅弄清楚哪个动词是真正的默认值已经足够难了,我建议您只使用ShellExecute并让shell处理其余动词。

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