C++ 相对路径.EXE名称上的::ShellExecute和静态CFile::GetStatus()的路径搜索顺序是否应该相同?

C++ 相对路径.EXE名称上的::ShellExecute和静态CFile::GetStatus()的路径搜索顺序是否应该相同?,c++,winapi,mfc,shellexecute,cfile,C++,Winapi,Mfc,Shellexecute,Cfile,在我的MFC应用程序中,我正在做类似的事情 CFileStatus fs; if (CFile::GetStatus("MyOtherProg.exe", fs)) { // found the file ::ShellExecute(NULL, NULL, "MyOtherProg.exe", NULL, NULL, SW_SHOW); } 但是在静态CFile::GetStatus中找到的文件的完整路径不是由::ShellExecute执行的路径(它具有相同的名称,但在不同

在我的MFC应用程序中,我正在做类似的事情

CFileStatus fs;
if (CFile::GetStatus("MyOtherProg.exe", fs))
  {
  // found the file
  ::ShellExecute(NULL, NULL, "MyOtherProg.exe", NULL, NULL, SW_SHOW);
  }
但是在静态CFile::GetStatus中找到的文件的完整路径不是由::ShellExecute执行的路径(它具有相同的名称,但在不同的文件夹中运行不同版本的“MyOtherProg.exe”)

我曾在不同的PC上使用相同的O/S(Win7 64位),在不同的文件夹中使用不同的“MyOtherProg.exe”集,尝试过这种方法。这两台PC的ShellExecute运行的都与在CFile::GetStatus中找到的相同。一台电脑总是运行版本3,另一台电脑总是运行版本2(为什么不一致?)

注1:在2台电脑中,至少有3个版本已“安装”,但路径中未安装任何版本。有些在桌面上有快捷方式,如果这是一些未记录的功能的话

注2:它们都是“MyOtherProg.exe”的不同版本,但安装在不同的目录中

注3:通过::ShellExecute运行的完整路径与我在任务栏“开始”菜单下的搜索编辑字段中键入“MyOtherProg.exe”时找到的路径相同。但是为什么CFile::GetStatus找到的不是同一个?为什么一台电脑的版本是2,而另一台电脑的版本是3

注4:在两台电脑上,运行命令“MyOtherProg.exe”的搜索列表仅显示1个版本(尽管在一台电脑上安装了3个版本,在另一台电脑上安装了4个不同版本,第五个版本是“调试”版本)。3个版本的电脑始终只列出版本2,5个版本的电脑始终只列出版本3。


  • CFile::GetStatus
    扩展与工作目录的相对路径
  • ShellExecute
    使用进程创建搜索顺序查找文件。这在
    CreateProcess
    文档中有描述。除了此处列出的路径外,还会搜索每个应用程序的路径

简言之,这意味着单独使用
CFile::GetStatus
并不适合您心目中的任务。您必须重新创建shell搜索

但你为什么要这么做?合理的做法是直接调用
ShellExecute
,并检查错误。让它执行搜索,因为它知道规则。由于
ShellExecute
有缺陷的错误报告,您应该调用
ShellExecuteEx


另一方面,如果您只想像当前调用
CFile::GetStatus
一样在工作目录中搜索,则使用绝对路径而不是相对路径。我怀疑这是你想做的,但为了完整起见,请提一下

CFile::GetStatus()
不搜索路径,而是使用
GetFullPathName()
扩展提供的文件路径,它只是在路径前面加上当前工作目录和驱动器(如果需要)。结果路径可能存在,也可能不存在。如果您需要在路径上定位文件,请使用
SearchPath
,然后使用完全限定路径。它们是否应该相同是一个有点空的问题,因为您发现它们显然不相同。要确保在每种情况下都获得相同的exe,您唯一能做的就是首先解析路径,正如@William所指出的。哪个::CreateProcess参数是::ShellExecute的lpFile参数映射到的?看起来它可以映射到CreateProcess的lpApplicationName(第一个参数)或lpCommandLine(第二个参数),并且“搜索”的规则是不同的。从我调用ShellExecute时看到的行为来看,它可能是lpApplicationName?再看一看,我认为这是我问题的关键。我希望ShellExecute将
lpFile
作为
lpApplicationName
lpParameters
作为
lpCommandLine
传递。CreateProcess:lpApplicationName。。。也可以指定部分名称。对于部分名称,函数使用当前驱动器和当前目录来完成规范;我希望ShellExecute文档能够解释这一点,或者指向CreateProcess文档。这就是我看到的(即它不在调用进程的文件夹中)