I have seen similar questions (e.g. Encode/Decode URLs in C++). But, for me:
CString strURL;
DWORD dwSize = _MAX_PATH;
if (InternetCanonicalizeUrl(strFile, strURL.GetBuffer(_MAX_PATH), &dwSize, ICU_BROWSER_MODE))
{
// still has backslash
AfxMessageBox(strURL);
}
strURL.ReleaseBuffer();
strURL = strFile;
strURL.Replace(L"\\", L"/");
strURL = L"file:///" + strURL;
AfxMessageBox(strURL);
Using InternetCanonicalizeUrl
did not work:
file://
and not file:///
.\
was not replaced with /
.I did it manually and my version of the URL works with my subsequent WebView2
function. To clarify, the path itself was built with ::GetTempPath()
and/or ::GetTempFileName()
.
Why did the built-in API call not do what I needed?
Why did the built-in API call not do what I needed?
The best answer I can give to this "Why?" part of your question is that the "WinInet" library component of the WinAPI uses (or, at least, is based on) Internet Explorer internally … and we all know how dodgy and non-conformant IE can be.
However, the documentation for the InternetCanonicalizeUrl
function does actually suggest (albeit cryptically) an alternative if you want a more complete/compliant result:
In Internet Explorer 4.0 and later,
InternetCanonicalizeUrl
always functions as if theICU_BROWSER_MODE
flag is set. Client applications that must canonicalize the entire URL should use eitherCoInternetParseUrl
(with the actionPARSE_CANONICALIZE
and the flagURL_ESCAPE_UNSAFE
) orUrlCanonicalize
.
I experimented with the latter alternative (it seemed the simpler of the two) and found a relatively trivial fix for your issue:
// if (InternetCanonicalizeUrl(strFile, strURL.GetBuffer(_MAX_PATH), &dwSize, ICU_BROWSER_MODE))
if (UrlCanonicalize(strFile, strURL.GetBuffer(_MAX_PATH), &dwSize, 0) == S_OK)
{
AfxMessageBox(strURL);
}
strURL.ReleaseBuffer();
In the test I ran (using the path from GetTempPath()
), this gives the full file:///
prefix and replaces all backslashes with forward slashes.
(You will need to #include <shlwapi.h>
somewhere in your code and will also need to include the "Shlwapi.lib" library when linking.)
On the use of three slashes after a file:
prefix for "localhost" URLs, see this Q/A on Super User.