Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 设置webbrowser中加载的自定义HTML的URL_C#_.net_Winforms_Webbrowser Control - Fatal编程技术网

C# 设置webbrowser中加载的自定义HTML的URL

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

我在WebBrowser控件中加载了一些html文本,它的uri大约为:空白。现在,我想将其Uri设置为其他内容,而无需导航到该链接


我该怎么做?

网络浏览器的文档对象通过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→ 清除复选标记。