我正在使用 C++Builder XE7 创建一个项目,用户可以在其中单击按钮打开 Web 链接,例如打开支持页面,或在社交媒体上分享他的经验。为此,我使用了 ShellExecute()
函数,它运行良好,除了一个按钮。
当我点击这个按钮时,什么也没有发生。 ShellExecute()
函数返回没有错误(返回值为 42),但是我的默认浏览器打不开,网页根本不显示。
这是我的 ShellExecute()
实现
const HINSTANCE result = ::ShellExecute(handle, "open", url.c_str(), NULL, NULL, SW_SHOWDEFAULT);
我还尝试了 ShellExecuteEx()
函数:
::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))
url
参数包含我要打开的网站链接。出于安全原因,我不能将它作为示例发布在这里,但是我在我的浏览器 (FireFox) 中对其进行了测试并且它运行良好。另一方面,如果我通过将 url
内容替换为 Google 的网站来执行我的代码,一切都会按预期工作。
handle
就是父框架的Handle
参数。
我还尝试调整 ShellExecute/Ex()
参数,例如 hwnd
和 nShow
字段,但没有改变。
谁能指出我哪里出了问题?
最佳答案
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!
在此示例中,您必须对双引号和空格进行 URL 编码,因为这些不是 query part of an URL 的有效字符.
通过用 %22
替换双引号和用 %20
替换空格来修复它。我建议使用类似 UrlEscape()
的函数正确编码 URL。
虽然大多数浏览器都对用户输入有错误容忍度,并且也会接受没有有效编码的 URL,但最好严格遵守规范,因为不能保证容错度。
此外,当 URL 作为命令行参数传递给与 URL 协议(protocol)关联的命令时,双引号会产生问题。这是因为双引号是用于定义包含空格的命令行参数的保留字符。
例如,在我的机器上,http
协议(protocol)与以下命令关联(参见 HKEY_CLASSES_ROOT\http\shell\open\command
):
"C:\Program Files (x86)\Mozilla Firefox\firefox.exe"-osint -url "%1"
您可以看到双引号已经用于包含最后一个参数,如果您在 URL 中使用未编码双引号,这显然会搞砸。
正确编码用于 ShellExecuteEx()
的 URL 的示例:
#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();
}
关于c++ - ShellExecute(和 ShellExecuteEx)对我的 URL 不做任何事情,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44889672/