5

我们公司正在将我们的帮助系统迁移到 Flare 下的 HTML5 格式。我们还在 URI 命令行上使用 Flare CSHID 为帮助系统添加了基于主题的访问,用于直接访问主题,例如index.html#CSHID=GettingStarted启动GettingStarted.html帮助页面。

我们的应用程序是用 C++ 编写的,并利用 Win32ShellExecute()函数生成与 HTTP 关联的默认应用程序来显示帮助系统。我们注意到,ShellExecute()当没有指定主题标签时,它可以正常工作,例如

ShellExecute(NULL, _T("open"), _T("c:\\Help\\index.html"), NULL, NULL, SW_SHOWNORMAL);

此函数将启动与查看 HTML 页面相关的默认浏览器,在这种情况下,File:///协议处理程序将启动,浏览器将启动,您将file:///c:/Help/index.html在地址栏中看到。

但是,一旦您添加了#主题的信息,就ShellExecute()无法打开页面

ShellExecute(NULL,_T("open"),_T("c:\\Help\\index.html#cshid=GettingStarted"),NULL,NULL,SW_SHOWNORMAL);

如果浏览器完全打开,您将被定向到file:///c:/Help/index.html 而没有#cshid=GettingStarted主题标识。

请注意,这只是一个问题,如果 File 协议处理程序通过 参与ShellExecute(),如果帮助系统存在于网络上,并且 Http 或 Https 协议处理程序参与,一切都很好。

对于我们的客户,其中一些在专用 LAN 上,我们不能总是依赖 Internet 访问,因此我们的帮助系统必须与应用程序一起提供。

4

4 回答 4

4

在与微软的 MSDN 团队反复讨论之后,他们审查了 ShellExecute() 调用的源代码,并确定是的,当在 ShellExecute() 中处理基于 File:/// 的 URL 时,ShellExecute() 调用将在启动默认浏览器并发送 HTML 页面以打开之前,去掉 # 和它在 # 之后找到的任何数据。MS 的立场是他们故意这样做是为了防止注入到函数中。

解决方案是通过在 URL 中搜索 # 来增强 ShellExecute() 调用,如果找到,我们将使用 URL 手动启动默认浏览器。这是伪代码

void WebDrive_ShellExecute(LPCTSTR szURL)
{
    if ( _tcschr(szURL,_T('#')) )
    {
        //
        //Get Default Browser from Registry, then launch it.
        //
        ::RegGetStr(HKCR,_T("HTTP\\Shell\\Open\\Command"),szBrowser);
        ::CreateProcess ( NULL, szBrowser + _T(" ") + szURL, NULL, NULL, FALSE, 0, NULL, NULL, &sui, &pi);
    }
    else
        ShellExecute(NULL,_T("open"),szURL,NULL,NULL,SW_SHOWNORMAL);
}

当然,c++ 代码还有更多内容,但这种通用设计对我们有用。

于 2014-10-10T17:56:15.637 回答
1

使用FindExecutable()获取默认浏览器并将完整的帮助文件路径及其查询 ( ?) 和片段 ( #) 作为lpParameters参数传递给ShellExecute()。他们不会在那里被剥光。
如果它是商店应用程序(很可能是 Microsoft Edge),则处理此案例。

伪 C 代码:

if (FindExecutable(_T("c:\Help\index.html"), NULL, szBrowser)
{
    if (szBrowser == _T("C:\WINDOWS\system32\LaunchWinApp.exe"))
    {
        // default browser is a Windows Store App
        szBrowser = _T("shell:AppsFolder\Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge");
    }
}
else
{
    szBrowser = szURL;
    szURL = NULL;
}

ShellExecute(NULL, NULL, szBrowser, szURL, NULL, SW_SHOWNORMAL);
于 2019-07-03T14:07:51.767 回答
1

我尝试了 WebDrive 的解决方案,但它并没有真正在 Windows 10 上运行。

“HTTP\Shell\Open\Command”默认值设置为 Internet Explorer 路径,无论我的默认浏览器设置如何。但是,对于 Internet Explorer,该解决方案确实有效。

在 Windows 10 上获取默认浏览器路径的过程有点不同(如何确定 Windows 默认浏览器(在开始菜单的顶部)),但即使这样,也不能保证解决方案能够正常工作,具体取决于浏览器。例如,对我来说,它不适用于 Edge。

为了让它与 Edge 一起工作,我必须在 URL 中添加“file:///”——但这也使得 URL 可以与 ShellExecute() 一起工作。所以,至少在 Windows 10 上,我需要做的就是:

ShellExecute(NULL,_T("open"),_T("file:///c:/Help/Default.html#cshid=1648"),NULL,NULL,NULL);

更新:上述停止工作几个月前。我最终所做的是通过临时文件,如下所述:https ://forums.madcapsoftware.com/viewtopic.php?f=9&t=28376#p130613

于 2018-05-02T22:58:43.213 回答
0

我没有在 Qt 应用程序中使用 ShellExecute 以外的任何方法解决了这个问题

QString currentpath = QDir::currentPath();
QString url = "/help//html/index.html#current";
QString full_url = "file:///" + currentpath + url;
QByteArray full_url_arr= full_url.toLocal8Bit();
LPCSTR lp = LPCSTR(full_url_arr.constData());
ShellExecute(NULL, "open", lp, NULL, NULL, SW_SHOWNORMAL);

于 2020-08-17T14:57:58.503 回答