I have code (and for decades) that:
- given some HTML
string
in memory - hand that document to an Internet Explorer object
- and make Internet Explorer (separate process) visible
- all without littering the user's computer with temporary files
In other words:
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;
}
- Pros:
- Cons:
- hard-codes the use of Internet Explorer, rather than the user's preferred browser
But IE is going away
Microsoft recently announced that Internet Explorer (the product) will no longer come with Windows, but Internet Explorer (the programming api) will continue to work:
As announced today, Microsoft Edge with IE mode is officially replacing the Internet Explorer 11 desktop application on Windows 10. As a result, the Internet Explorer 11 desktop application will go out of support and be retired on June 15, 2022 for certain versions of Windows 10.
Out of scope at the time of this announcement (unaffected):
- Internet Explorer mode in Microsoft Edge
- Internet Explorer platform (MSHTML/Trident), including WebOC
- Internet Explorer 11 desktop application on:
- Windows 8.1
- Windows 7 Extended Security Updates (ESU)
- Windows 10 Server SAC (all versions)
- Windows 10 IoT Long-Term Servicing Channel (LTSC) (all versions)
- Windows 10 Server LTSC (all versions)
- Windows 10 client LTSC (all versions)
What is the MSHTML (Trident) engine? How does that relate to IE mode?
The MSHTML (Trident) engine is the underlying platform for Internet Explorer 11. This is the same engine used by IE mode and it will continue to be supported (in other words, unaffected by this announcement). WebOC will also continue to be supported. If you have a custom or third-party app that relies on the MSHTML platform, you can expect it to continue to work.
(emphasis mine)
Which means that Microsoft is breaking 23 years of backwards compatibility - and replacing it with...nothing.
So i need to find a way to replace it.
- spawn the default browser
- give it HTML i want to display
- all without temporary files
Temporary Buggy Hack
For now i am using @corbin-c's buggy workaround:
procedure SpawnBrowserWithSource(const szSourceHTML: UnicodeString);
var
html: RawByteString; //utf8 encoded
dataUri: string;
szPath: string;
function GetDefaultBrowser: string;
var
nch: DWORD;
hr: HRESULT;
begin
//Get the default browser (i.e. the association for .html file type)
nch := 1000;
SetLength(Result, nch);
hr := AssocQueryString(0, ASSOCSTR_EXECUTABLE, '.html', nil, PChar(Result), @nch);
if hr = E_POINTER then
begin
//Try again if the buffer was too small
SetLength(Result, nch);
hr := AssocQueryString(0, ASSOCSTR_EXECUTABLE, '.html', nil, PChar(Result), @nch);
end;
OleCheck(hr);
SetLength(Result, nch-1); //don't include the null terminator
end;
begin
{
With Internet Explorer being deprecated, this also means that the automation will fail.
So we try to marshall the HTML into base64 encoded URI, and spawn that.
So spawn it as:
data:text/html;base64,[base64 encoded html]
E.g.:
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('Could not locate default browser');
ExecuteFile(szPath, dataUri);
end;