代码之家  ›  专栏  ›  技术社区  ›  Peter

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

  •  3
  • Peter  · 技术社区  · 16 年前

    我正在使用WinFormsWebBrowser控件在Windows窗体应用程序中显示某些内容。我正在使用documentText属性编写生成的HTML。那部分工作得很出色。现在我想在标记中使用一些图像。(不过,我也希望使用链接的CSS和JavaScript,只要嵌入它就可以解决这个问题。)

    我在谷歌上搜索了好几天,似乎找不到标题问题的答案。

    我尝试使用相对引用:app exe在bin\debug中。这些图像位于项目根目录下的“images”目录中。我已经设置了要在编译时复制到输出目录的图像,因此它们最终会出现在bin\debug\images*中。然后我用一个类似于“图片…”的引用,认为它是相对于exe的。但是,当我在嵌入式浏览器窗口中查看图像属性时,我看到图像URL是“about:blankimages/*”。当HTML被写入控件时,一切似乎都与“about:blank”相关。由于缺少位置上下文,我无法确定用于相对文件资源引用的内容。

    我浏览了一下控件的属性,看看是否有方法设置一些内容来修复这个问题。我创建了一个空白的HTML页面,并使用“navigate()”方法将浏览器指向它,使用文件的完整本地路径。当浏览器向空白页报告本地“文件:///…”路径时,效果良好。然后我再次使用document.write()写入浏览器。浏览器现在再次报告“about:blank”作为URL。

    除了将动态HTML结果写入实际文件之外,是否没有其他方法引用文件资源?

    我将尝试最后一件事:构建图像的绝对文件路径并将其写入HTML。我的HTML是使用序列化对象的XML的XSL转换生成的,因此我需要使用一些XSL参数,因为我不太熟悉这些参数,因此需要花费一些额外的时间。

    5 回复  |  直到 14 年前
        1
  •  4
  •   Ken Wootton    16 年前

    下面是我们要做的,尽管我应该提到,我们使用自定义Web浏览器来删除诸如右键单击和查看良好的旧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">
    
        2
  •  1
  •   Peter    16 年前

    我弄明白了。

    我只是将exe目录的完整解析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" />
    
        3
  •  0
  •   Peter    16 年前

    我最终使用了和肯建议的基本相同的东西。但是,我没有手动附加文件前缀,而是使用uribuilder类用“文件”协议构建完整的URI。

    当我们在更真实的位置,程序文件中测试应用程序时,这也解决了随后的问题。空间已编码,但当使用标准系统路径引用文件时,操作系统无法处理编码字符(即“C:\Program%20files…”)。使用真正的uri值(file:///c:/program files/…)有效。

        4
  •  0
  •   Roark Fan    16 年前

    或者,保留与样式相关的普通链接,删除HTML转换代码,而不是嵌入类似C Web服务器 this 在exe中,然后将WebControl指向内部URL,如localhost:8199/myapp/

        5
  •  0
  •   Orwellophile    15 年前

    肯的代码遗漏了一些它需要工作的东西。我已经对它进行了修改,并创建了一个新的方法,可以使事情稍微自动化。

    只需这样调用静态方法:

    html = HtmlFormatter.ReplaceImagePathAuto(html);
    

    HTML中匹配文件:://applicationpath/的所有链接都将与当前工作目录交换。如果要指定备用位置,则包含原始静态方法(加上缺少的位)。

    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);
        }
    }