I'm creating a project with C++Builder XE7, in which a user can click on a button to open a web link, e.g. to open a support page, or to share his experience on a social media. For that, I use the ShellExecute()
function, and it works well, except for one button.
When I click on this button, simply nothing happens. The ShellExecute()
function returns without error (the returned value is 42), but my default browser does not open, and the web page isn't shown at all.
Here is my ShellExecute()
implementation
const HINSTANCE result = ::ShellExecute(handle, "open", url.c_str(), NULL, NULL, SW_SHOWDEFAULT);
I also tried the ShellExecuteEx()
function:
::SHELLEXECUTEINFO info;
std::memset(&info, 0, sizeof(info));
info.cbSize = sizeof(info);
info.hwnd = handle;
info.lpVerb = "open";
info.lpFile = url.c_str();
info.nShow = SW_SHOWDEFAULT;
if (!::ShellExecuteEx(&info))
The url
parameter contains the website link I am trying to open. For security reasons, I cannot post it here as a sample, however I tested it in my browser (FireFox) and it works well. On the other hand, if I execute my code by just replacing the url
content with Google's website, all works as expected.
The handle
is just the Handle
parameter of the parent frame.
I also tried to tweak the ShellExecute/Ex()
parameters, like the hwnd
and nShow
fields, but no change.
Can anybody point me to what is wrong?
The url is formatted like this: http:// www. mysite.xxx/selectPage.php?arg1=xxx&arg2=yyy&...&argX=a text containing "quotes" and some %26amp%3b special chars!
In this example you have to URL-encode the double quotes and the spaces because these are not valid characters for the query part of an URL.
Fix it by replacing double quotes with %22
and spaces with %20
. I suggest to use a function like UrlEscape()
to properly encode the URL.
Although most browsers have an error tolerance for user input and will also accept an URL which does not have valid encoding, it's better to strictly follow the spec because you are not guaranteed that tolerance.
In addition, the double quotes will make problems when the URL is passed as a command-line argument to the command associated with the URL protocol. This is because double quotes are reserved characters for defining command-line parameters that contain spaces.
For instance, on my machine the http
protocol is associated with the following command (see HKEY_CLASSES_ROOT\http\shell\open\command
):
"C:\Program Files (x86)\Mozilla Firefox\firefox.exe" -osint -url "%1"
You can see that the double quotes are already used to enclose the last parameter, which obviously gets messed up if you have unencoded double quotes within the URL.
Example for correctly encoding an URL for use with ShellExecuteEx()
:
#include <windows.h>
#include <Shellapi.h>
int main()
{
::CoInitialize(nullptr);
SHELLEXECUTEINFOW info{ sizeof(info) };
info.fMask = SEE_MASK_NOASYNC; // because we exit process after ShellExecuteEx()
info.lpVerb = L"open";
info.lpFile = L"http://www.google.de/search?q=ShellExecuteEx%20URL%20%22double%20quotes%22";
info.nShow = SW_SHOWDEFAULT;
if( !::ShellExecuteExW( &info ) )
{
DWORD err = ::GetLastError();
printf("ShellExecuteEx failed with error %d\n", err );
}
::CoUninitialize();
}