自动生成 HTML 文件并尝试在 IE 中打开它有时会显示空白页

Posted

技术标签:

【中文标题】自动生成 HTML 文件并尝试在 IE 中打开它有时会显示空白页【英文标题】:Auto-generating HTML file & trying to open it in IE sometimes shows a blank page 【发布时间】:2015-04-25 17:43:46 【问题描述】:

我有一个与 Internet Explorer (IE) 相关的奇怪行为。我的目标是将报告生成为 html 标记并通过 Web 浏览器将其显示给用户。 (由于我的软件在我们的企业环境中使用,并且大多数默认情况下都有 IE 网络浏览器,因此我仅在 IE 中观察到此问题。)

该软件是作为基于 MFC 对话框的应用程序编写的,每天(早上 7:30)从重复的任务计划程序任务中运行。 (该任务设置为仅在用户登录时运行,始终如此。这是一个单用户帐户系统,该用户永远不会注销。这些机器也一直处于开机状态。)

在启动时,我的软件会生成 HTML 标记,将其保存在临时文件中,然后让 IE 将其显示给用户。就是这样。 (目标基本上是自动化此报告并在人们开始他们的一天时将其显示在屏幕上。)

所以我基本上使用了以下代码:

TCHAR buffTempFldr[MAX_PATH] = 0;
::GetTempPath(MAX_PATH, buffTempFldr);
StringCchCat(buffTempFldr, MAX_PATH, L"Log Report.htm");

//strHtml = CStringA with HTML markup of report in 8-bit ASCII format

HANDLE hFile = ::CreateFile(buffTempFldr, GENERIC_READ | GENERIC_WRITE, 
    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
    CREATE_ALWAYS, 0, NULL);
if(hFile != INVALID_HANDLE_VALUE)

    DWORD dwcbWrtn;
    ::WriteFile(hFile, (BYTE *)strHtml.GetString(), strHtml.GetLength(), &dwcbWrtn, NULL);
    ::CloseHandle(hFile);

    BOOL bInitted = SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE));

    //Show in Web Browser (IE by default)
    int nRetSH = (int)ShellExecute(NULL, L"open", buffTempFldr, NULL, NULL, SW_SHOWNORMAL);

    if(nRetSH > 32)
    
        //Success
    

    if(!bInitted)
        CoUninitialize();

问题是这在大多数情况下都有效,但可能有 10% 的时间用户得到一个空的(空白)HTML 页面。只有在他们点击刷新后,页面才会显示实际的报告。

显然这让用户感到困惑,所以我想看看为什么会这样?

PS。执行此操作的计算机运行的是 Windows 7 Professional 和 IE v.11,并定期安装更新。

【问题讨论】:

CloseHandle() 之前尝试FlushFileBuffers()。此外,"open" 应该是 NULL 来执行文件的默认动词,if(!bInitted) 应该是 if(bInitted) @RemyLebeau:谢谢。我不确定我为什么选择if(!bInitted)。我猜是脑子放屁;)至于FlushFileBuffers(),我认为CloseHandle()本质上就是这样做的。否则所有的操作系​​统缓存都没有意义。 快速更新。刚刚实施了您的建议,并且在前几次都有效。但是在第 3 次或第 4 次尝试时,我又得到了一个空的 IE 屏幕。所以只有在我按下 F5 后,内容才会出现。嗯...我很困惑为什么?与我手动测试它的唯一不同(没有时间表)是屏幕可能已关闭,并且屏幕保护程序之前可能已显示。这可能是个问题吗? 【参考方案1】:

我可能已经深究了。

这看起来像是 IE 11 渲染引擎中的错误。 (有趣的是,我在一台装有 IE 8 的机器上运行它并且运行良好。)我偶然发现了这一点。当 IE 显示一个空白页面时,如果我稍微调整它的窗口大小,我的 HTML 标记就会立即绘制出来。这似乎也只有当我通过 IE 运行我的页面并且屏幕在省电模式下关闭时才会发生(尽管运行屏幕保护程序也可能这样做——我还没有完全测试它。)

所以目前我选择使用以下“hack”来唤醒屏幕,然后再调用我的 ShellExecute 方法:

SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)-1);
::Sleep(500);

CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
ShellExecute(NULL, NULL, strSaveFileTo, NULL, NULL, SW_SHOWNORMAL);

但我会强烈建议不要使用它,因为它会产生竞争条件,或者换句话说,无法知道首先会发生什么,屏幕被唤醒或 IE 页面正在显示.

作为一种可行的解决方案,尽管人们可能会考虑使用不会出现此问题的其他网络浏览器,例如 Google Chrome 或 Firefox。

【讨论】:

以上是关于自动生成 HTML 文件并尝试在 IE 中打开它有时会显示空白页的主要内容,如果未能解决你的问题,请参考以下文章

网页浏览器打开文件不要下载怎么设置

强制 IE 下载未打开的文件

使用VB自动化IE“目标另存为”

IE浏览器无法打开本地html文件

网页如何查看源代码

delphi中如何把一个webbroker生成的dll在ie中打开?