ShellExecute(和 ShellExecuteEx)对我的 URL 没有任何作用

ShellExecute (and ShellExecuteEx) do nothing with my URL

我正在使用 C++Builder XE7 创建一个项目,用户可以在其中单击一个按钮来打开 Web link,例如打开支持页面,或在社交媒体上分享他的经验。为此,我使用 ShellExecute() 函数,它运行良好,除了一个按钮。

当我点击这个按钮时,什么也没有发生。 ShellExecute()函数returns没有错误(返回值为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 参数包含我正在尝试打开的网站 link。出于安全原因,我无法在此处 post 将其作为示例,但我在浏览器 (FireFox) 中对其进行了测试并且运行良好。另一方面,如果我通过将 url 内容替换为 Google 的网站来执行我的代码,一切都会按预期工作。

handle只是父框架的Handle参数

我也尝试调整 ShellExecute/Ex() 参数,例如 hwndnShow 字段,但没有改变。

谁能指出我哪里出了问题?

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 协议关联的命令时,双引号会产生问题。这是因为 双引号是用于定义包含空格的命令行参数的保留字符.

例如,在我的机器上 http 协议与以下命令关联(参见 HKEY_CLASSES_ROOT\http\shell\open\command):

"C:\Program Files (x86)\Mozilla Firefox\firefox.exe" -osint -url "%1"

您可以看到双引号已经用于括起最后一个参数,如果您在 URL 中有 未编码 双引号,显然会搞砸了。

正确编码 URL 以与 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();
}