IE退役后如何调用默认浏览器打开内存HTML字符串且不生成临时文件
我有一段已经使用了数十年的代码,其逻辑如下:
- 接收内存中的一段HTML
string内容 - 将该文档传递给Internet Explorer对象
- 让独立进程的Internet Explorer可见并渲染内容
- 全程不会在用户设备上生成临时文件造成冗余
代码示例如下:
void SpawnIEWithSource(string szSourceHTML) { IWebBrowser ie = (IWebBrowser)CoCreateInstance(CLASS_InternetExplorer, null, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER, UuidOf(IUnknown)); ie.Navigate2("about:blank"); ie.Document.Write(szSourceHtml); ie.Document.Close; ie.Visible = True; }
- 优点:
- 可在独立进程打开HTML报表
- 无需生成临时文件
- 缺点:
- 硬编码使用Internet Explorer,无法适配用户的默认浏览器设置
但IE浏览器即将停止服务
微软近期宣布,Internet Explorer产品将不再内置在Windows系统中,但Internet Explorer对应的编程API仍可继续使用:
今日公告显示,搭载IE模式的Microsoft Edge将正式替代Windows 10上的Internet Explorer 11桌面应用。因此,部分版本Windows 10的Internet Explorer 11桌面应用将于2022年6月15日停止支持并退役。
本次公告未覆盖(不受影响)的范围:
- Microsoft Edge中的IE模式
- Internet Explorer平台(MSHTML/Trident),包括WebOC
- 运行在以下系统的Internet Explorer 11桌面应用:
- Windows 8.1
- Windows 7扩展安全更新(ESU)版本
- Windows 10 Server SAC(全版本)
- Windows 10 IoT长期服务通道(LTSC)(全版本)
- Windows 10 Server LTSC(全版本)
- Windows 10客户端LTSC(全版本)
什么是MSHTML(Trident)引擎?它和IE模式有什么关联?
MSHTML(Trident)引擎是Internet Explorer 11的底层平台,也是IE模式使用的同款引擎,将持续获得支持(即不受本次公告影响)。WebOC也将继续被支持。如果你有依赖MSHTML平台的自定义或第三方应用,可以放心它会继续正常运行。
(以上为标注的重点内容)
这意味着微软打破了23年的向后兼容性,且没有提供对应的替代方案。因此我需要找到原有方案的替代实现,满足以下要求:
- 调用系统默认浏览器
- 传入需要展示的HTML内容
- 全程不生成临时文件
临时过渡方案(存在缺陷)
目前我使用@corbin-c提供的临时方案,存在一定缺陷,代码如下:
procedure SpawnBrowserWithSource(const szSourceHTML: UnicodeString); var html: RawByteString; //utf8编码 dataUri: string; szPath: string; function GetDefaultBrowser: string; var nch: DWORD; hr: HRESULT; begin //获取默认浏览器(即.html文件类型的关联程序) nch := 1000; SetLength(Result, nch); hr := AssocQueryString(0, ASSOCSTR_EXECUTABLE, '.html', nil, PChar(Result), @nch); if hr = E_POINTER then begin //如果缓冲区过小则重试 SetLength(Result, nch); hr := AssocQueryString(0, ASSOCSTR_EXECUTABLE, '.html', nil, PChar(Result), @nch); end; OleCheck(hr); SetLength(Result, nch-1); //去除末尾的空终止符 end; begin { 随着IE被弃用,原有的自动化方案也会失效。 因此我们尝试将HTML编码为base64 URI后启动浏览器加载。 格式如下: data:text/html;base64,[base64编码的html内容] 示例: data:text/html;base64,PEhUTUw+PEJPRFk+SGVsbG8sIHdvcmxkITwvQk9EWT48L0hUTUw+ 调用示例: ExecuteFile('data:text/html;base64,PEhUTUw+PEJPRFk+SGVsbG8sIHdvcmxkITwvQk9EWT48L0hUTUw+'); } html := UnicodeToRawByteString(#$FEFF+szSourceHTML, CP_UTF8); dataUri := 'data:text/html;base64,'+TBase64.ToBase64String(html); szPath := GetDefaultBrowser; if szPath = '' then raise Exception.Create('无法定位默认浏览器'); ExecuteFile(szPath, dataUri); end;
扩展阅读
- .NET: 如何让WebBrowser控件在IE中启动、显示HTML、脱离当前进程运行?
- 如何将WebBrowser控件的渲染模式切换为IE9标准模式?
- 如何用Lua启动浏览器并直接传入HTML字符串?
- 如何创建IWebBrowser2控件?
内容的提问来源于stack exchange,提问作者Ian Boyd
相关产品推荐
相关产品推荐

