简体   繁体   English

ShellExecute(和ShellExecuteEx)对我的网址不执行任何操作

[英]ShellExecute (and ShellExecuteEx) do nothing with my URL

I'm creating a project with C++Builder XE7, in which a user can click on a button to open a web link, eg to open a support page, or to share his experience on a social media. 我正在使用C ++ Builder XE7创建一个项目,在该项目中,用户可以单击按钮来打开Web链接,例如,打开支持页面或在社交媒体上分享他的经验。 For that, I use the ShellExecute() function, and it works well, except for one button. 为此,我使用了ShellExecute()函数,除了一个按钮之外,它运行良好。

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. ShellExecute()函数返回没有错误(返回值为42),但是我的默认浏览器没有打开,并且网页也没有显示。

Here is my ShellExecute() implementation 这是我的ShellExecute()实现

const HINSTANCE result = ::ShellExecute(handle, "open", url.c_str(), NULL, NULL, SW_SHOWDEFAULT);

I also tried the ShellExecuteEx() function: 我还尝试了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))

The url parameter contains the website link I am trying to open. url参数包含我要打开的网站链接。 For security reasons, I cannot post it here as a sample, however I tested it in my browser (FireFox) and it works well. 出于安全原因,我无法将其作为示例发布在此处,但是我在浏览器(FireFox)中对其进行了测试,并且效果很好。 On the other hand, if I execute my code by just replacing the url content with Google's website, all works as expected. 另一方面,如果我仅通过用Google网站替换url内容来执行代码,则所有工作都将按预期进行。

The handle is just the Handle parameter of the parent frame. handle只是父框架的Handle参数。

I also tried to tweak the ShellExecute/Ex() parameters, like the hwnd and nShow fields, but no change. 我还尝试调整ShellExecute/Ex()参数,例如hwndnShow字段,但没有更改。

Can anybody point me to what is wrong? 有人可以指出我出了什么问题吗?

The url is formatted like this: http:// www. 网址的格式如下:http:// www。 mysite.xxx/selectPage.php?arg1=xxx&arg2=yyy&...&argX=a text containing \\"quotes\\" and some %26amp%3b special chars! mysite.xxx/selectPage.php?arg1=xxx&arg2=yyy&...&argX=包含\\“ quotes \\”和一些%26amp%3b特殊字符的文本!

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 . 在此示例中,您必须对双引号和空格进行URL编码,因为它们对于URL查询部分不是有效字符。

Fix it by replacing double quotes with %22 and spaces with %20 . 通过将双引号替换为%22并将空格替换为%20 I suggest to use a function like UrlEscape() to properly encode the URL. 我建议使用类似UrlEscape()的函数来正确编码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. 尽管大多数浏览器对用户输入都有容错能力,并且还会接受没有有效编码的URL,但最好严格遵循规范,因为不能保证一定的容忍度。

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. 另外,当URL作为命令行参数传递给与URL协议相关联的命令时,双引号会引起问题。 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 ): 例如,在我的计算机上, http协议与以下命令关联(请参阅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. 您会看到双引号已经用于括住最后一个参数,如果您在URL中有未编码的双引号,则显然会弄乱。

Example for correctly encoding an URL for use with ShellExecuteEx() : 正确编码与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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM