如何在WinForms WebBrowser控件生成的HTML中引用本地资源?

3
我正在使用winforms webbrowser控件在Windows Forms应用程序中显示一些内容。我正在使用DocumentText属性来编写生成的HTML。这部分工作非常出色。现在我想在标记中使用一些图像。(我也希望使用链接的CSS和JavaScript,但是可以通过嵌入解决。)
我已经搜索了几天,似乎找不到标题问题的答案。
我尝试使用相对引用:应用程序exe位于bin \ debug中。图像位于项目根目录下的“Images”目录中。我已将图像设置为在编译时复制到输出目录,因此它们最终位于bin \ debug \ Images *中。所以我使用类似这样的引用“Images ...”,认为它将相对于exe。然而,当我在嵌入的浏览器窗口中查看图像属性时,我看到图像URL为“about:blankImages / *”。当HTML写入控件时,所有内容似乎都是相对于“about:blank”。由于缺少位置上下文,我无法确定用于相对文件资源引用的内容。
我查看了控件的属性,看看是否有一种方法可以设置某些东西来修复这个问题。我创建了一个空白的html页面,并使用“Navigate()”方法将浏览器指向该页面,使用完整的本地路径到文件。这与浏览器报告本地“file:///…”路径到空白页一起工作得很好。然后我再次写入浏览器,这次使用Document.Write()。同样,浏览器现在报告URL为“about:blank”。
除了将动态HTML结果编写到实际文件中之外,还有没有其他引用文件资源的方法?
我将尝试最后一件事:构建图像的绝对文件路径并将其写入HTML。我的HTML是使用序列化对象的XML的XSL转换生成的,因此我需要使用一些XSL参数进行操作,这需要额外的时间,因为我不太熟悉它们。
5个回答

5

这是我们所做的事情,但我应该提一下,我们使用自定义的网络浏览器来删除像右键点击并查看好老的IE上下文菜单这样的功能:

public class HtmlFormatter
{
    /// <summary>
    /// Indicator that this is a URI referencing the local
    /// file path.
    /// </summary>
    public static readonly string FILE_URL_PREFIX = 
        "file://";

    /// <summary>
    /// The path separator for HTML paths.
    /// </summary>
    public const string PATH_SEPARATOR = "/";
}


// We need to add the proper paths to each image source
// designation that match where they are being placed on disk.
String html = HtmlFormatter.ReplaceImagePath(
    myHtml, 
    HtmlFormatter.FILE_URL_PREFIX + ApplicationPath.FullAppPath + 
    HtmlFormatter.PATH_SEPARATOR);

基本上,您需要拥有具有文件URI的图像路径,例如

<img src="file://ApplicationPath/images/myImage.gif">

内置的网络浏览器可以配置为不显示常规上下文菜单:IsWebBrowserContextMenuEnabled = false。 - Peter
OOI PATH_SEPARATOR已经在框架中定义 - Path.AltDirectorySeparatorChar - Fraser

1

我已经搞定了。

我只需将完整的解析URL传递给包含带有图像标签的HTML输出的XSL转换即可:

XsltArgumentList lstArgs = new XsltArgumentList();
lstArgs.AddParam("absoluteRoot", string.Empty, Path.GetFullPath("."));

然后我只是在所有图像前缀中加入了参数值:

<img src="{$absoluteRoot}/Images/SilkIcons/comment_add.gif" align="middle" border="0" />

0

Ken的代码缺少一些必要的东西才能正常工作。我已经进行了修订,并创建了一个新的方法,应该会自动化一些事情。

只需这样调用静态方法:

html = HtmlFormatter.ReplaceImagePathAuto(html);

所有与 file://ApplicationPath/ 匹配的 HTML 链接都将被替换为当前工作目录。如果您想指定另一个位置,原始静态方法已包含(以及它缺少的部分)。

public class HtmlFormatter
{

    public static readonly string FILE_URL_PREFIX = "file://";
    public static readonly string PATH_SEPARATOR = "/";
    public static String ReplaceImagePath(String html, String path)
    {
        return html.Replace("file://ApplicationPath/", path);
    }
    /// <summary>
    /// Replaces URLs matching file://ApplicationPath/... with Executable Path
    /// </summary>
    /// <param name="html"></param>
    /// <returns></returns>
    public static String ReplaceImagePathAuto(String html)
    {
        String executableName = System.Windows.Forms.Application.ExecutablePath;
        System.IO.FileInfo executableFileInfo = new System.IO.FileInfo(executableName);
        String executableDirectoryName = executableFileInfo.DirectoryName;
        String replaceWith = HtmlFormatter.FILE_URL_PREFIX
            + executableDirectoryName
            + HtmlFormatter.PATH_SEPARATOR;

        return ReplaceImagePath(html, replaceWith);
    }
}

0

最终我使用了与Ken建议的基本相同的东西。但是,我没有手动添加文件前缀,而是使用UriBuilder类构建了完整的URI,其中包含“file”协议。

这也解决了我们在更现实的位置Program Files中测试应用程序时遇到的后续问题。空格被编码,但是当使用标准系统路径引用文件时(即“C:\ Program%20Files ...”),操作系统无法处理编码字符。使用真正的URI值(file:///C:/Program Files/...)可以解决该问题。


0

或者,保留您的普通样式相对链接,放弃HTML转换代码,而是在您的exe中嵌入一个C# Web服务器,例如this,然后将您的WebControl指向您的内部URL,如localhost:8199/myapp/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接