I have an embedded HTML resource (helloworld.htm) inside my Visual Studio project. (Ie, I've added an HTML file to the project and set its properties to "Embedded Resource".
Within the same application I have a WebBrowser control.
I'd like to direct the WebBrowser control to display the HTML resource using the res:// protocol.
But I can't figure out the exact format needed to address an embedded resource using this style of URL.
Any ideas? Thanks!
I know this thread is dead, but I had to do this yesterday and couldn't get any of these methods to work. So I did a little research and found the method below, using the Stream class. I thought I'd post it here just in case somebody else runs into the same nonsense:
Stream docStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("NameSpace.HTMLPage.html");
WebBrowser.DocumentStream = docStream;
This worked for me without any tinkering, and it was so simple. I hope it benefits somebody else!
The res: protocol is not dead and is still a great way to embed webpages into Windows applications using a WebBrowser
control. Unfortunately, it seems to me there are two types of resources in exe and dll files out there: C resources and .net resources. It may possible to embed C resources in a .net dll but I haven't figured out how to yet.
To answer your question, the res protocol is documented at here but actually building the dll or exe is the tricky part. The res protocol is simple enough. The basic gist of it is you specify res://, follow that by the path to the executable or dll (just the dll name if it's in the current path). For HTML type resources, follow that with the filename. Here is a recent MSDN article the talks about some known problems with the res protocol: http://support.microsoft.com/kb/220830.
Building the dll or exe resources can be a little bit tricky. For easiest results, make all of your resources of type HTML (even your .js, .png, .jpg files). Instead of naming your resources with a #defined resource identifier, modern res files allow you to name the files with a string. Doing this will make your life a lot easier.
Advanced Tip: Having folder names in the resource name is tricky; I haven't figured it our yet. I think you may be able to simulate folders by putting slashes in the resource name, but I think res protocol gets confused by the slashes thinking the first part of the path is the resource type. Explicitly specifying the resource type may alleviate this.
Advanced Tip 2: For the path newer versions of IE can deal with the '\' character, but you can use '%5C' as a substitute for '\' if you need to specify the absolute or relative location of the dll or exe.
Additional Resource:
MSDN Social: Webbrowser and res: protocol
DelphiDabbler: How to create and use HTML resource files
res://project.exe/helloworld.htm
This is the little helper class and how to call it:
How to call:
StreamResourceInfo info =
ResourceHelper.GetResourceStreamInfo(@"Resources/GraphicUserGuide.html");
if (info != null)
{
WebBrowser.NavigateToStream(info.Stream);
}
Helper class:
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));
}
// ******************************************************************
}
}
webBrowser1.DocumentText = ResourceinWebBrowser.Properties.Resources.HTML.ToString();
Where:
webBrowser1
is the WebBrowser
control
ResourceinWebBrowser
is your exe / Project Name.
HTML
is the name of your embedded html resource
The easiest way, maybe not the safest or most sane, is to have a Settings variable that made up the base web page, place your own marker tags to REPLACE when streaming the strings in packets. This way, once the non-dynamic portions of the web page is completed, you only need to render the dynamic portions to REPLACE in the string. Then set the DoumentText = stringWebStream. Be sure to set AllowNavigation = True.
I know that it's been asked a long time ago, but here's how IE interprets the res:
protocol:
res://sFile[/sType]/sID
sFile Percent-encoded path and file name of the module that contains the resource.
sType Optional. String or numerical resource type. This can be either a custom resource or one of the predefined resource types that
are recognized by the FindResource function. If a numerical resource
type is specified, the number of the identifier must follow a #
character. If this parameter is not specified, the default resource
type is RT_HTML or RT_FILE.
sID String or numerical identifier of the resource. If a numerical identifier is specified, the actual number of the identifier, not the
identifier itself, must follow a # character. See the example for more
information.