ShellExecute() launch .CHM and PDF file not work in Window 7
-
Now we have another small project also created in C++, it also launch .CHM file from help menu: void CMainFrame::LaunchHelp(CString FilePath) { SHELLEXECUTEINFO sei; sei.cbSize = sizeof(SHELLEXECUTEINFO); sei.fMask = NULL; sei.hwnd = NULL; sei.lpVerb = "open"; sei.lpFile = FilePath; sei.lpParameters= NULL; sei.nShow = SW_SHOWMAXIMIZED; sei.hInstApp = NULL; sei.lpIDList = NULL; sei.lpClass = NULL; sei.hkeyClass = NULL; sei.dwHotKey = NULL; sei.hIcon = NULL; sei.hProcess = NULL; sei.lpDirectory = NULL; int ReturnCode = ::ShellExecuteEx(&sei); switch(ReturnCode) { case ERROR_FILE_NOT_FOUND: AfxMessageBox("The specified file was not found."); break; case ERROR_PATH_NOT_FOUND: AfxMessageBox("The specified path was not found."); break; case ERROR_ACCESS_DENIED: AfxMessageBox("Access to the specified file is denied."); break; } } I works fine in Window 7, I copy this function to my application (also created in C++), but after compile and test it in Window 7, still doesn't work, do we need change some settings to make app work in Window 7? I compare the settings, the only difference are that 1: in C++ - >Code Generation -> Use run time library: I use Multithreaded DLL, they use Multlhreaded; 2: in General Microsoft Foundation Classes: I use Use MFC in a Shared Library; they use Use MFC in a Static Library. Thanks!
You're calling
ShellExecute_**Ex**_
but testing the return value for the forSE_ERR_
values? WithShellExecuteEx
[^], the return value is true/false and the more information is provided byGetLastError()
. For backward compatibility, the SE_ERR_ codes are placed inhInst
member of the structure. Try this instead:SHELLEXECUTEINFO sei = { sizeof(sei) }; // Will zero out the structure, no need to set NULL on everything
sei.fMask = SEE_MASK_NOASYNC // Important when you don't have a message loop
sei.lpFile = FilePath;
sei.nShow = SW_SHOWMAXIMIZED; // Annoying to force apps to open full screen
if (false == ShellExecuteEx(&sei))
{
// Check GetLastError() here
}/* Charles Oppermann */ http://weblogs.asp.net/chuckop
-
You're calling
ShellExecute_**Ex**_
but testing the return value for the forSE_ERR_
values? WithShellExecuteEx
[^], the return value is true/false and the more information is provided byGetLastError()
. For backward compatibility, the SE_ERR_ codes are placed inhInst
member of the structure. Try this instead:SHELLEXECUTEINFO sei = { sizeof(sei) }; // Will zero out the structure, no need to set NULL on everything
sei.fMask = SEE_MASK_NOASYNC // Important when you don't have a message loop
sei.lpFile = FilePath;
sei.nShow = SW_SHOWMAXIMIZED; // Annoying to force apps to open full screen
if (false == ShellExecuteEx(&sei))
{
// Check GetLastError() here
}/* Charles Oppermann */ http://weblogs.asp.net/chuckop
Right,
GetExitCodeProcess()
likewise also gets the error code.#include
#include
#includeint main()
{SHELLEXECUTEINFO sei = {0}; sei.cbSize = sizeof(SHELLEXECUTEINFO); sei.lpVerb = \_T("open"); sei.lpFile = \_T("C:\\\\windows\\\\help.CHM"); sei.fMask = SEE\_MASK\_INVOKEIDLIST; sei.nShow = SW\_SHOWDEFAULT; DWORD exitCode; int RetVal = GetExitCodeProcess(sei.hProcess, &exitCode); cout<<"Errorcode "<
-
The code below works and launches a helpfile in Windws 7.
#include
#include
#includeint main()
{SHELLEXECUTEINFO sei = {0}; sei.cbSize = sizeof(SHELLEXECUTEINFO); sei.lpVerb = \_T("open"); sei.lpFile = \_T("C:\\\\windows\\\\help.CHM"); sei.fMask = SEE\_MASK\_INVOKEIDLIST; sei.nShow = SW\_SHOWDEFAULT; DWORD exitCode; int RetVal = GetExitCodeProcess(sei.hProcess, &exitCode); cout<<"Errorcode "<
Now I cannot simply say that ::ShellExecuteEx(&sei) doesn't work in Window 7. The problem is that it doesn't work in my application created before. I have a app created using VC++ 6.0 last year, everything is fine except that I cannot open .CHM file from it. Today I create a new application in MFC in VC++ 6.0, then use the exactly same function as the old application, it can open the .CHM file without any problem. I check all the project settings for both application, they are same, why same function works in one application, but failed in another application?
-
You're calling
ShellExecute_**Ex**_
but testing the return value for the forSE_ERR_
values? WithShellExecuteEx
[^], the return value is true/false and the more information is provided byGetLastError()
. For backward compatibility, the SE_ERR_ codes are placed inhInst
member of the structure. Try this instead:SHELLEXECUTEINFO sei = { sizeof(sei) }; // Will zero out the structure, no need to set NULL on everything
sei.fMask = SEE_MASK_NOASYNC // Important when you don't have a message loop
sei.lpFile = FilePath;
sei.nShow = SW_SHOWMAXIMIZED; // Annoying to force apps to open full screen
if (false == ShellExecuteEx(&sei))
{
// Check GetLastError() here
}/* Charles Oppermann */ http://weblogs.asp.net/chuckop
-
The code below works and launches a helpfile in Windws 7.
#include
#include
#includeint main()
{SHELLEXECUTEINFO sei = {0}; sei.cbSize = sizeof(SHELLEXECUTEINFO); sei.lpVerb = \_T("open"); sei.lpFile = \_T("C:\\\\windows\\\\help.CHM"); sei.fMask = SEE\_MASK\_INVOKEIDLIST; sei.nShow = SW\_SHOWDEFAULT; DWORD exitCode; int RetVal = GetExitCodeProcess(sei.hProcess, &exitCode); cout<<"Errorcode "<
-
Yes, you are right, ShellExecuteEx() return true or false. But still cannot solve my problem.
Andraw111 wrote:
Yes, you are right, ShellExecuteEx() return true or false.
But still cannot solve my problem.Okay, but what is it returning? True or False? If false, did you check
GetLastError()
? What was it's value?/* Charles Oppermann */ http://weblogs.asp.net/chuckop
-
Andraw111 wrote:
Yes, you are right, ShellExecuteEx() return true or false.
But still cannot solve my problem.Okay, but what is it returning? True or False? If false, did you check
GetLastError()
? What was it's value?/* Charles Oppermann */ http://weblogs.asp.net/chuckop
-
Andraw111 wrote:
Yes, you are right, ShellExecuteEx() return true or false.
But still cannot solve my problem.Okay, but what is it returning? True or False? If false, did you check
GetLastError()
? What was it's value?/* Charles Oppermann */ http://weblogs.asp.net/chuckop
Finally I found what cause the .CHM file cannot open in Window 7. In my MFC application, I have a project setting: Link -> Output ->Reserve field, I put "0x40000000". I create a testing application, if I don't set "0x40000000" to Reserve field, it works fine, otherwise, it cannot open .CHM file in Window 7. Even I know the reason, I still cannot solve the problem, since our project is very large, if I remove that setting, when I run my application I get "XX MFC application has encountered a problem and needs to close....".
-
Thanks for reply, it return 8. But strange thing is that if I create a brand new MFC project and use the same codes to open .CHM file, it works fine, why?
I strongly suspect that COM initialization is at issue here[^]. Earlier, I mentioned that COM has to be initialized as follows:
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)
This is why I think you're new project works and the old one doesn't. Is your old project using multithreaded COM? If so, the calls might fail. [Just saw your other post that resolves your issue. I'm posting this for other people who might encounter ShellExecute problems.]
/* Charles Oppermann */ http://weblogs.asp.net/chuckop
-
I strongly suspect that COM initialization is at issue here[^]. Earlier, I mentioned that COM has to be initialized as follows:
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)
This is why I think you're new project works and the old one doesn't. Is your old project using multithreaded COM? If so, the calls might fail. [Just saw your other post that resolves your issue. I'm posting this for other people who might encounter ShellExecute problems.]
/* Charles Oppermann */ http://weblogs.asp.net/chuckop