【问题标题】:Google Chrome broke ShellExecute()?谷歌浏览器破坏了 ShellExecute()?
【发布时间】:2023-03-16 13:41:02
【问题描述】:

多年来,我一直在使用 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 作为参数。谢谢!

【问题讨论】:

  • FWIW,这在我的机器上完美运行,Chrome 设置为默认浏览器。您可能想看看损坏的机器上是否安装了其他东西...
  • 它在我的机器上不起作用,但是通过启动 .htm 相关应用程序的技巧,它现在可以工作了,所以我很高兴。谢谢!
  • WinExec 实际上仍然保留在 x64 中,一直到当前的 Windows afaik 并经过测试。我不相信他们有充分的理由将其删除,所以就把它留在里面。
  • 我感觉这可能与 Chrome 在后台选项卡中打开链接有关。也许用户没有注意到,或者这个选项卡被错误地隐藏了。根据稀疏的用户报告,Opera 似乎也受到了这个问题的困扰。我自己,我没有见过这样的失败,所以相信根本原因是某些 PC 上严重的 shell 关联损坏,假设不仅仅是它们“缺少”正在打开的背景选项卡。
  • 另外请注意,正如我在答案的评论中所指出的,如果您的应用程序正在提升运行,请小心启动提升的浏览器。这显然是浏览器不希望出现的状态。当然,仅适用于 NT6+。

标签: .net google-chrome shellexecute


【解决方案1】:

这是适用于所有浏览器的代码。诀窍是在 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;
}

【讨论】:

  • 我同意这里的前提似乎是最有效的——我必须做一些实验来确定这一点。如果 ShellExecute 失败,则回退。请注意,您可以回退到 HTTP 协议而不是 .HTM 处理程序,但这是 ShellExecute 应该 所做的,因此如果您更改代码来执行此操作,您可能会遇到二次失败。还有另一个问题:在 NT 6+ 中从提升的进程启动浏览器时,浏览器本身会启动提升。这是不希望的状态。有一些方法可以解决这个问题,但是 !topic
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 2012-03-23
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 2012-06-12
    • 2016-05-09
    • 2013-12-18
    • 2011-11-01
    • 2018-12-30
    相关资源
    最近更新 更多