C# 设置webbrowser中加载的自定义HTML的URL
我在WebBrowser控件中加载了一些html文本,它的uri大约为:空白。现在,我想将其Uri设置为其他内容,而无需导航到该链接C# 设置webbrowser中加载的自定义HTML的URL,c#,.net,winforms,webbrowser-control,C#,.net,Winforms,Webbrowser Control,我在WebBrowser控件中加载了一些html文本,它的uri大约为:空白。现在,我想将其Uri设置为其他内容,而无需导航到该链接 我该怎么做?网络浏览器的文档对象通过URL名字对象加载数据。有一个漂亮的图表展示了url名字和浏览器之间的关系 您可以通过文档的IPersistStreamInit接口手动将名字对象或流加载到文档中。这就是Winform的webbrowser类在实现DocumentStream和DocumentText属性时所做的。文档将调用源的IMoniker::GetDisp
我该怎么做?网络浏览器的文档对象通过URL名字对象加载数据。有一个漂亮的图表展示了url名字和浏览器之间的关系 您可以通过文档的IPersistStreamInit接口手动将名字对象或流加载到文档中。这就是Winform的webbrowser类在实现DocumentStream和DocumentText属性时所做的。文档将调用源的IMoniker::GetDisplayName来获取url。但是,Windows窗体中的“从流加载”实现未实现IMoniker,加载的文档的基址约为:空
有一个关于在实现url名字对象的示例。在页面上搜索LoadHtmlIntoBrowserstring html,string sBaseUrl。有两种方法可以为加载到web浏览器控件中的自定义html内容设置URL: 使用html标记 通过实现IMoniker接口Git Repo:[r-aghaei/WebBrowserHtmlContentBaseUrl] 下载 第一个是非常简单和直接的。对于第二个解决方案,我创建了一个woring示例。你可以在这里找到它:
重要调试说明:要调试应用程序,请转到调试菜单禁用NotImplementedException→ 窗户→ 异常设置→ 搜索System.NotImplementedException→ 清除复选标记。或者,如果它抛出异常,您可以在异常窗口中取消选中该异常。 如果按Ctrl+F5,则不会看到任何异常 注释 使用标记非常简单和直接,但我无法加载@font-face的相对地址。其余的事情都很好 IMoniker解决方案需要添加对SHDocVw的引用,该引用可以在reference manager窗口的COM选项卡中作为Microsoft Internet控件找到 信用证:感谢作者,另一个答案是盛江 解决方案1-使用标签 HTML元素指定用于文档中包含的所有相对URL的基本URL。文档中只能有一个元素 这样就可以像这样将一个标记注入到:
html = html.Replace(@"<head>", $@"<head><base href=""{new Uri(Application.StartupPath)}/""/>");
webBrowser1.DocumentText = html;
webBrowser1.SetHtmlContent(html, $@"{new Uri(Application.StartupPath)}/");
只需添加对SHDocVw的引用,并在项目中使用粘贴以下代码:
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using SHDocVw;
public static class WebBrowserExtensions
{
public static void SetHtmlContent(this System.Windows.Forms.WebBrowser webBrowser, string html, string baseUrl)
{
webBrowser.Navigate("about:blank");
var browser = (IWebBrowser2)webBrowser.ActiveXInstance;
var result = CreateStreamOnHGlobal(Marshal.StringToHGlobalAuto(html), true, out IStream stream);
if ((result != 0) || (stream == null))
return;
var persistentMoniker = browser.Document as IPersistMoniker;
if (persistentMoniker == null)
return;
IBindCtx bindContext = null;
CreateBindCtx((uint)0, out bindContext);
if (bindContext == null)
return;
var loader = new Moniker(baseUrl, html);
persistentMoniker.Load(1, loader, bindContext, (uint)0);
stream = null;
}
[DllImport("ole32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
static extern int CreateStreamOnHGlobal(IntPtr hGlobal, bool fDeleteOnRelease, out IStream istream);
[DllImport("ole32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
static extern int CreateBindCtx([MarshalAs(UnmanagedType.U4)] uint dwReserved, [Out, MarshalAs(UnmanagedType.Interface)] out IBindCtx ppbc);
[ComImport, ComVisible(true)]
[Guid("79EAC9C9-BAF9-11CE-8C82-00AA004BA90B")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
interface IPersistMoniker
{
void GetClassID([In, Out] ref Guid pClassID);
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int IsDirty();
void Load([In] int fFullyAvailable, [In, MarshalAs(UnmanagedType.Interface)] IMoniker pmk, [In, MarshalAs(UnmanagedType.Interface)] Object pbc, [In, MarshalAs(UnmanagedType.U4)] uint grfMode);
void SaveCompleted([In, MarshalAs(UnmanagedType.Interface)] IMoniker pmk, [In, MarshalAs(UnmanagedType.Interface)] Object pbc);
[return: MarshalAs(UnmanagedType.Interface)]
IMoniker GetCurMoniker();
}
class Moniker : IMoniker
{
public static Guid IID_IStream = new Guid("0000000c-0000-0000-C000-000000000046");
string baseUrl;
IStream stream;
public Moniker(string baseUrl, string content)
{
this.baseUrl = baseUrl;
CreateStreamOnHGlobal(Marshal.StringToHGlobalAuto(content), true, out stream);
}
public void GetDisplayName(IBindCtx pbc, IMoniker pmkToLeft, out string ppszDisplayName)
{
ppszDisplayName = this.baseUrl;
}
public void BindToStorage(IBindCtx pbc, IMoniker pmkToLeft, ref Guid riid, out object ppvObj)
{
ppvObj = null;
if (riid.Equals(IID_IStream))
ppvObj = (IStream)stream; ;
}
public void GetClassID(out Guid pClassID)
{
throw new NotImplementedException();
}
public int IsDirty()
{
throw new NotImplementedException();
}
public void Load(IStream pStm)
{
throw new NotImplementedException();
}
public void Save(IStream pStm, bool fClearDirty)
{
throw new NotImplementedException();
}
public void GetSizeMax(out long pcbSize)
{
throw new NotImplementedException();
}
public void BindToObject(IBindCtx pbc, IMoniker pmkToLeft, ref Guid riidResult, out object ppvResult)
{
throw new NotImplementedException();
}
public void Reduce(IBindCtx pbc, int dwReduceHowFar, ref IMoniker ppmkToLeft, out IMoniker ppmkReduced)
{
throw new NotImplementedException();
}
public void ComposeWith(IMoniker pmkRight, bool fOnlyIfNotGeneric, out IMoniker ppmkComposite)
{
throw new NotImplementedException();
}
public void Enum(bool fForward, out IEnumMoniker ppenumMoniker)
{
throw new NotImplementedException();
}
public int IsEqual(IMoniker pmkOtherMoniker)
{
throw new NotImplementedException();
}
public void Hash(out int pdwHash)
{
throw new NotImplementedException();
}
public int IsRunning(IBindCtx pbc, IMoniker pmkToLeft, IMoniker pmkNewlyRunning)
{
throw new NotImplementedException();
}
public void GetTimeOfLastChange(IBindCtx pbc, IMoniker pmkToLeft, out System.Runtime.InteropServices.ComTypes.FILETIME pFileTime)
{
throw new NotImplementedException();
}
public void Inverse(out IMoniker ppmk)
{
throw new NotImplementedException();
}
public void CommonPrefixWith(IMoniker pmkOther, out IMoniker ppmkPrefix)
{
throw new NotImplementedException();
}
public void RelativePathTo(IMoniker pmkOther, out IMoniker ppmkRelPath)
{
throw new NotImplementedException();
}
public void ParseDisplayName(IBindCtx pbc, IMoniker pmkToLeft, string pszDisplayName, out int pchEaten, out IMoniker ppmkOut)
{
throw new NotImplementedException();
}
public int IsSystemMoniker(out int pdwMksys)
{
throw new NotImplementedException();
}
}
}
我找不到Microsoft HTML控件我使用的Microsoft Internet控件是否可以基于您的建议,在重现该问题后,我启动了一个新的演示windows应用程序,只是一个带有打印按钮的表单,webBrowser1.SetHtmlContenthtmlData,$@{new UriApplication.StartupPath}/;webBrowser.Print;它在第一次点击时抛出一个异常,然后在第二次点击时打印,没有字体,只有背景图像,我尝试使用webbrowser,只显示html,没有打印,同样的场景,没有字体效果,只有背景,但这次没有异常,我想这是因为我不打印,只是浏览!调试菜单→ 窗户→ 异常设置→ 搜索System.NotImplementedException→ 清除复选标记。非常感谢您的努力,这不是问题,问题在于演示应用程序中只有背景url有效,而不是字体,在抛出异常后,我必须多次单击打印以在第二次或第三次打印。@AnynameDonotcare解决方案2适用于字体和其他资源。此外,您应该在调试时通过转到“调试”菜单忽略该异常→ 窗户→ 异常设置→ 搜索System.NotImplementedException→ 清除复选标记。