0
votes

From within my MFC App, I am doing something like

CFileStatus fs;
if (CFile::GetStatus("MyOtherProg.exe", fs))
  {
  // found the file
  ::ShellExecute(NULL, NULL, "MyOtherProg.exe", NULL, NULL, SW_SHOW);
  }

but the full path to the file found in the static CFile::GetStatus is NOT the one being executed by ::ShellExecute (it has the same name, but is running a different version of "MyOtherProg.exe", in a different folder).

I have tried this on different PCs with the same O/S (Win7 64 bit), with different sets of "MyOtherProg.exe" in various folders. Neither PC's ShellExecute runs the same one found in the CFile::GetStatus. One PC always ends up running version 3, another PC always ends up running version 2 (why isn't THAT consistent?).

Note 1: Across the 2 PCs, at least 3 versions are "installed", but NONE of them are installed in the PATH. Some DO have SHORTCUTS on the Desktop, if that is some undocumented feature.

Note 2: ALL of them are different versions of "MyOtherProg.exe", but installed in different directories.

Note 3: The full path of the one that ends up being run via ::ShellExecute is the same one found when I just type "MyOtherProg.exe" in the Search edit field below the Task Bar's START menu. But WHY is the one found by CFile::GetStatus NOT the SAME one? And why on one PC it's version 2, but on another PC its version 3?

Note 4: On both PCs, the resulting search list of the RUN command "MyOtherProg.exe" only shows 1 version (although on one PC, 3 versions are installed, and on the other PC 4 different versions are installed with a fifth one being a "debug" build). The PC with 3 versions always ONLY lists version 2, the PC with 5 versions always ONLY lists version 3.

1
CFile::GetStatus() does not search the path, rather it expands the supplied file path using GetFullPathName() which simply prepends path with the current working directory and drive (if needed). The resulting path may or may not exist. If you need to locate a file on the path, use SearchPath then use the fully qualified path.William
Whether they should be the same or not is a bit of a null question, as you've found they are evidently not. The only thing you can do to ensure that you get the same exe in each case is to resolve the path first, as @William pointed out.Roger Rowland

1 Answers

0
votes
  • CFile::GetStatus expands the relative path with the working directory.
  • ShellExecute looks for the file using the process creation search order. This is described in the CreateProcess documentation. As well as the paths listed there, the per-application path is searched.

In short this means that CFile::GetStatus alone is simply not suitable for the task you have in mind. You'd have to re-create the shell search.

But why would you do that? The logical thing to is to call ShellExecute directly and check for errors. Let it perform the search, because it knows the rules. Since ShellExecute has deficient error reporting you should rather call ShellExecuteEx.

On the other hand, if you only want to search in the working directory as you do with your current call to CFile::GetStatus then use an absolute rather than relative path. I doubt that this is what you want to do but mention it for completeness.