I have a weird problem in one of my projects lately regarding the Win32 API ShellExecute()
function.
The program is compiled using Visual C++ 2015, in ANSI mode.
int ret = (int)ShellExecuteA(0, "open", "C:\\Users\\Maverick\\stratum.jpg", NULL, NULL, SW_SHOWNORMAL);
printf("ShellExecute return value: %i\n", ret);
In the above code, ShellExecute()
returns 42, so it should be successful. However, it doesn't actually open the file.
I don't have privilege problems, and it fails with the same problem even when running the program as an administrator.
In fact, I can successfully run the file this way:
system("C:\\Users\\Maverick\\stratum.jpg");
I don't want to be forced to use system()
, though.
Also, before I migrated the project to a newer Visual Studio, I was using Visual C++ 6.0, and the code worked fine.
Any clues what may be the problem?
EDIT: ShellExecuteEx()
also returns successful (1), but does not open the file.
SHELLEXECUTEINFO ShExecInfo;
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = NULL;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = "C:\\Users\\Maverick\\stratum.jpg";
ShExecInfo.lpParameters = NULL;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOWNORMAL;
ShExecInfo.hInstApp = NULL;
int ret = (int)ShellExecuteExA(&ShExecInfo);
ShellExecute()
behaves, since it is a Win32 API function implemented at the OS layer. The same function gets called in both versions. In any case, try usingShellExecuteEx()
instead, it provides more accurate error reporting thanShellExecute()
does. Also consider replacing"open"
withNULL
to invoke the default action, which might not be"open"
to begin with, depending on the imaging software you have installed. – Remy LebeauShellExecute/Ex()
is successfully launching a new process, but that process is then failing to load the file. FromShellExecute/Ex's
perspective, its portion of work was successful. Unfortunately, there is no way to detect this kind of failure when usingShellExecute/Ex()
. You would have to invoke the target app manually, such as by usingFindExecutable()
andCreateProcess()
directly (which does not account for all the possible ways a file can be opened by the Shell, but should suffice for your particular example). – Remy LebeauShellExecuteEx()
returns aBOOL
, not anint
. If it returnsFALSE
, useGetLastError()
to get the actual error code. – Remy Lebeau