MS WebBrowser +嵌入式HTML资源+ res://协议

时间:2009-08-10 12:32:17

标签: html webbrowser-control embedded-resource

我的Visual Studio项目中有一个嵌入式HTML资源(helloworld.htm)。 (即,我已将HTML文件添加到项目中,并将其属性设置为“Embedded Resource”。

在同一个应用程序中,我有一个WebBrowser控件。

我想指示WebBrowser控件使用res:// protocol显示HTML资源。

但是我无法弄清楚使用这种URL来解决嵌入式资源所需的确切格式。

有什么想法吗?谢谢!

7 个答案:

答案 0 :(得分:12)

我知道这个帖子已经死了,但我昨天必须这样做,并且无法使这些方法中的任何一个工作。所以我做了一些研究,并使用Stream类找到了下面的方法。我以为我会把它发布在这里以防万一其他人遇到同样的废话:

Stream docStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("NameSpace.HTMLPage.html");
WebBrowser.DocumentStream = docStream;

这对我来说没有任何修修补补,而且非常简单。我希望它能让其他人受益!

答案 1 :(得分:7)

res:协议尚未消失,仍然是使用WebBrowser控件将网页嵌入Windows应用程序的绝佳方式。 不幸的是,在我看来,exe和dll文件中有两种类型的资源:C资源和.net资源。可以将C资源嵌入到.net dll中,但我还没弄明白怎么做。

要回答你的问题, res协议记录在here,但实际构建dll或exe是一个棘手的部分。 res协议很简单。它的基本要点是你指定res://,通过可执行文件或dll的路径(如果它在当前路径中只是dll名称)。对于HTML类型资源,请使用文件名。这是MSDN最近的一篇文章,讨论了res协议的一些已知问题:http://support.microsoft.com/kb/220830

构建dll或exe资源可能有点棘手。为了获得最简单的结果,请使用HTML类型的所有资源(甚至是.js,.png,.jpg文件)。现代res文件允许您使用字符串命名文件,而不是使用#defined资源标识符命名资源。这样做会让您的生活更轻松。

高级提示:在资源名称中包含文件夹名称很棘手;我还没想到它。我认为您可以通过在资源名称中添加斜杠来模拟文件夹,但我认为res协议被斜线混淆,认为路径的第一部分是资源类型。明确指定资源类型可以缓解这种情况。

高级提示2:对于路径,较新版本的IE可以处理'\'字符,但如果需要指定,可以使用'%5C'代替'\' dll或exe的绝对或相对位置。

其他资源:
MSDN Social: Webbrowser and res: protocol
DelphiDabbler: How to create and use HTML resource files

答案 2 :(得分:2)

res://project.exe/helloworld.htm

答案 3 :(得分:1)

这是小助手类以及如何调用它:

如何致电:

StreamResourceInfo info = 
    ResourceHelper.GetResourceStreamInfo(@"Resources/GraphicUserGuide.html");
if (info != null)
{
    WebBrowser.NavigateToStream(info.Stream);
}

助手类:

using System;
using System.Reflection;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Resources;

namespace HQ.Wpf.Util
{
    public class ResourceHelper
    {
        // ******************************************************************
        /// <summary>
        /// Load a resource WPF-BitmapImage (png, bmp, ...) from embedded resource defined as 'Resource' not as 'Embedded resource'.
        /// </summary>
        /// <param name="pathInApplication">Path without starting slash</param>
        /// <param name="assembly">Usually 'Assembly.GetExecutingAssembly()'. If not mentionned, I will use the calling assembly</param>
        /// <returns></returns>
        public static BitmapImage LoadBitmapFromResource(string pathInApplication, Assembly assembly = null)
        {
            if (assembly == null)
            {
                assembly = Assembly.GetCallingAssembly();
            }

            return new BitmapImage(ResourceHelper.GetLocationUri(pathInApplication, assembly));
        }

        // ******************************************************************
        /// <summary>
        /// The resource should be defined as 'Resource' not as 'Embedded resource'.
        /// </summary>
        /// <param name="pathWithoutLeadingSlash">The path start with folder name (if any) then '/', then ...</param>
        /// <param name="assembly">If null, then use calling assembly to find the resource</param>
        /// <returns></returns>
        public static Uri GetLocationUri(string pathWithoutLeadingSlash, Assembly assembly = null)
        {
            if (pathWithoutLeadingSlash[0] == '/')
            {
                pathWithoutLeadingSlash = pathWithoutLeadingSlash.Substring(1);
            }

            if (assembly == null)
            {
                assembly = Assembly.GetCallingAssembly();
            }

            return new Uri(@"pack://application:,,,/" + assembly.GetName().Name + ";component/" + pathWithoutLeadingSlash, UriKind.Absolute);
        }

        // ******************************************************************
        /// <summary>
        /// The resource should be defined as 'Resource' not as 'Embedded resource'.
        /// Example:            
        ///     StreamResourceInfo info = ResourceHelper.GetResourceStreamInfo(@"Resources/GraphicUserGuide.html");
        ///     if (info != null)
        ///     {
        ///         WebBrowser.NavigateToStream(info.Stream);
        ///     }
        /// </summary>
        /// <param name="path">The path start with folder name (if any) then '/', then ...</param>
        /// <param name="assembly">If null, then use calling assembly to find the resource</param>
        /// <returns></returns>
        public static StreamResourceInfo GetResourceStreamInfo(string path, Assembly assembly = null)
        {
            if (assembly == null)
            {
                assembly = Assembly.GetCallingAssembly();
            }

            return Application.GetResourceStream(ResourceHelper.GetLocationUri(path, assembly));
        }

        // ******************************************************************

    }
}

答案 4 :(得分:0)

webBrowser1.DocumentText = ResourceinWebBrowser.Properties.Resources.HTML.ToString();

其中:

  • webBrowser1WebBrowser控件
  • ResourceinWebBrowser是你的exe /项目名称。
  • HTML是嵌入式html资源的名称

答案 5 :(得分:0)

最简单的方法,也许不是最安全或最明智的方法,是有一个构成基本网页的设置变量,在数据包中流式传输字符串时,将自己的标记标记放置到REPLACE。这样,一旦完成网页的非动态部分,您只需要在字符串中将动态部分渲染为REPLACE。然后设置DoumentText = stringWebStream。一定要设置AllowNavigation = True。

答案 6 :(得分:0)

我知道很久以前就被问过,但是here's how IE解释了res:协议:

  

RES:// sFile [/ STYPE] / SID

     

sFile 包含资源的模块的百分比编码路径和文件名。

     

sType 可选。字符串或数字资源类型。这可以是自定义资源,也可以是预定义资源类型之一   被FindResource函数识别。如果是数字资源   指定了type,标识符的编号必须遵循#   字符。如果未指定此参数,则为默认资源   type是RT_HTML或RT_FILE。

     

sID 资源的字符串或数字标识符。如果指定了数字标识符,则标识符的实际编号,而不是   标识符本身,必须遵循#字符。请参阅示例了解更多信息   信息。