Google Chrome 破坏了 ShellExecute()?

发布于 2024-07-05 09:05:35 字数 622 浏览 4 评论 0原文

多年来,我一直使用 ShellExecute() API 从我的应用程序中启动默认的 Web 浏览器。 就像这样:

ShellExecute( hwnd, _T("open"), 
    _T("http://www.winability.com/home/"), 
    NULL, NULL, SW_NORMAL );

直到几周前谷歌发布了 Chrome 浏览器时,它一直运行良好。 现在,如果计算机上安装了 Chrome,ShellExecute API 将不再打开网页。

有人知道如何解决这个问题吗? (没有检测到 Chrome 并显示一条消息,告诉用户这是 Chrome 的错?)

编辑:Sergey 提供的代码似乎有效,所以我接受它作为“答案”。 只是我不喜欢对 WinExec 的调用:MSDN 上写到 WinExec 的提供只是为了与 16 位应用程序兼容。 IOW,它可能会停止与任何服务包一起工作。 我没有尝试过,但如果它已经停止在 Windows x64 上运行,我也不会感到惊讶,因为它根本不支持 16 位应用程序。 因此,我将使用 ShellExecute,而不是 WinExec,并像 Sergey 的代码一样从注册表中获取路径,并将 URL 作为参数。 谢谢!

For years I've been using ShellExecute() API to launch the default web browser from within my applications. Like this:

ShellExecute( hwnd, _T("open"), 
    _T("http://www.winability.com/home/"), 
    NULL, NULL, SW_NORMAL );

It's been working fine until a couple of weeks ago, when Google released its Chrome browser. Now, if Chrome is installed on the computer, the ShellExecute API no longer opens a web page.

Has anyone figured out yet how to solve this problem? (Short of detecting Chrome and displaying a message telling the user it's Chrome's fault?)

EDIT: the code provided by Sergey seems to work, so I've accepted it as "the" answer. Except that I don't like the call to WinExec: MSDN reads that WinExec is provided only for compatibility with 16-bit applications. IOW, it may stop working with any Service Pack. I did not try it, but I would not be surprised if it has already stopped working with Windows x64, since it does not support 16-bit applications at all. So, instead of WinExec, I'm going to use ShellExecute, with the path taken from the registry like Sergey's code does, and the URL as the argument. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

黯淡〆 2024-07-12 09:05:35

这是适用于所有浏览器的代码。 诀窍是如果 ShellExecute 失败则调用 WinExec。

HINSTANCE GotoURL(LPCTSTR url, int showcmd)
{
    TCHAR key[MAX_PATH + MAX_PATH];

    // First try ShellExecute()
    HINSTANCE result = 0;

    CString strURL = url;

    if ( strURL.Find(".htm") <0 && strURL.Find("http") <0 )
        result = ShellExecute(NULL, _T("open"), url, NULL, NULL, showcmd);

    // If it failed, get the .htm regkey and lookup the program
    if ((UINT)result <= HINSTANCE_ERROR) {

        if (GetRegKey(HKEY_CLASSES_ROOT, _T(".htm"), key) == ERROR_SUCCESS) {
            lstrcat(key, _T("\\shell\\open\\command"));

            if (GetRegKey(HKEY_CLASSES_ROOT,key,key) == ERROR_SUCCESS) {
                TCHAR *pos;
                pos = _tcsstr(key, _T("\"%1\""));
                if (pos == NULL) {                     // No quotes found
                    pos = strstr(key, _T("%1"));       // Check for %1, without quotes
                    if (pos == NULL)                   // No parameter at all...
                        pos = key+lstrlen(key)-1;
                    else
                        *pos = '\0';                   // Remove the parameter
                }
                else
                    *pos = '\0';                       // Remove the parameter

                lstrcat(pos, _T(" \""));
                lstrcat(pos, url);
                lstrcat(pos, _T("\""));
                result = (HINSTANCE) WinExec(key,showcmd);
            }
        }
    }

    return result;
}

Here is the code that works across all browsers. The trick is to call WinExec if ShellExecute fails.

HINSTANCE GotoURL(LPCTSTR url, int showcmd)
{
    TCHAR key[MAX_PATH + MAX_PATH];

    // First try ShellExecute()
    HINSTANCE result = 0;

    CString strURL = url;

    if ( strURL.Find(".htm") <0 && strURL.Find("http") <0 )
        result = ShellExecute(NULL, _T("open"), url, NULL, NULL, showcmd);

    // If it failed, get the .htm regkey and lookup the program
    if ((UINT)result <= HINSTANCE_ERROR) {

        if (GetRegKey(HKEY_CLASSES_ROOT, _T(".htm"), key) == ERROR_SUCCESS) {
            lstrcat(key, _T("\\shell\\open\\command"));

            if (GetRegKey(HKEY_CLASSES_ROOT,key,key) == ERROR_SUCCESS) {
                TCHAR *pos;
                pos = _tcsstr(key, _T("\"%1\""));
                if (pos == NULL) {                     // No quotes found
                    pos = strstr(key, _T("%1"));       // Check for %1, without quotes
                    if (pos == NULL)                   // No parameter at all...
                        pos = key+lstrlen(key)-1;
                    else
                        *pos = '\0';                   // Remove the parameter
                }
                else
                    *pos = '\0';                       // Remove the parameter

                lstrcat(pos, _T(" \""));
                lstrcat(pos, url);
                lstrcat(pos, _T("\""));
                result = (HINSTANCE) WinExec(key,showcmd);
            }
        }
    }

    return result;
}
和影子一齐双人舞 2024-07-12 09:05:35

在听到 ShellExecute 在少数系统上失败的报告后,我实现了一个与 Sergey Kornilov 给出的示例类似的功能。 这是大约一年前的事了。 相同的前提 - 对 .HTM 文件处理程序进行直接 HKCR 查找。

然而,事实证明,一些用户拥有将自己注册为“打开”.htm 文件(而不是“编辑”它们)的编辑器(例如 UltraEdit)。 因此,如果 ShellExecute 失败,则此辅助方法在这些情况下也将失败。 它会按照 shell 协会错误的指示打开编辑器。

因此,用户应该使用 HTTP 处理程序,或者至少优先于 HTML 处理程序。

After hearing reports of ShellExecute failing on a minority of systems, I implemented a function similar to the example given by Sergey Kornilov. This was about a year ago. Same premise - Do a direct HKCR lookup of the .HTM file handler.

However, it turns out that some users have editors (e.g. UltraEdit) that register themselves to 'open' .htm files (instead of 'edit' them). Thus, if ShellExecute fails, this secondary method will also fail in those cases. It opens the editor, as the shell association errantly instructs.

Thus, the user should use the HTTP handler instead, or at least in preference of the HTML handler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文