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!
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 "<
-
Dear all, HINSTANCE handle = ShellExecute(NULL, NULL, strHlpFile, NULL, NULL, SW_SHOW); I create a application in MFC, it works fine in Window XP and return 42 value, but if run it in Window 7, it cannot open the .CHM or PDF file, the return code is 8. What's the problem? how can I solve issue? I try to use system() to launch .CHM or PDF file, it works fine in both Window XP and Window 7, but it has MS-DOS black screen there, how can I let MS-DOS not shown? Thank you very much!
Have you initialized COM first? From the remarks section on ShellExecute()[^]:
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)
Can you use ShellExecuteEx[^]? ShellExecuteEx is preferable in this case because you'll get better result information.
Andraw111 wrote:
I try to use system() to launch .CHM or PDF file, it works fine in both Window XP and Window 7, but it has MS-DOS black screen there, how can I let MS-DOS not shown?
The
system()
C runtime function would not be appropriate here, as you are a Win32 application. Try this, from a command prompt, typestart myfile.chm
and report on what happens. Same for Runas./* Charles Oppermann */ http://weblogs.asp.net/chuckop
-
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