.net - visual - ¿Cómo hago referencia a un recurso local en HTML generado en el control WinForms WebBrowser?
webbrowser url c# (5)
Estoy usando un control de navegador web de winforms para mostrar algo de contenido en una aplicación de formularios de Windows. Estoy usando la propiedad DocumentText para escribir el HTML generado. Esa parte está funcionando espectacularmente. Ahora quiero usar algunas imágenes en el marcado. (También preferiría usar CSS y JavaScript vinculados, sin embargo, eso se puede resolver simplemente incrustándolo).
He estado buscando en Google en el transcurso de varios días y parece que no puedo encontrar una respuesta a la pregunta del título.
Intenté usar una referencia relativa: el exe de la aplicación está en bin / debug. Las imágenes viven en el directorio "Imágenes" en la raíz del proyecto. He configurado las imágenes para que se copien en el directorio de salida en la compilación, por lo que terminan en bin / debug / Images *. Entonces uso una referencia como esta "Imágenes ..." pensando que será relativa al exe. Sin embargo, cuando miro las propiedades de la imagen en la ventana del navegador incrustado, veo que la URL de la imagen es "about: blankImages / *". Todo parece ser relativo a "sobre: en blanco" cuando HTML se escribe en el control. Al carecer de contexto de ubicación, no puedo entender qué usar para una referencia de recurso de archivo relativa.
Busqué en las propiedades del control para ver si hay una manera de establecer algo para arreglar esto. Creé una página html en blanco y señalé el navegador usando el método "Navigate ()", usando la ruta local completa al archivo. Esto funcionó bien con el navegador que informaba la ruta local "file: /// ..." a la página en blanco. Luego volví a escribir en el navegador, esta vez usando Document.Write (). De nuevo, el navegador ahora informa "sobre: en blanco" como la URL.
Si no se escriben los resultados HTML dinámicos en un archivo real, ¿no hay otra forma de referenciar un recurso de archivo?
Voy a intentar una última cosa: construir rutas de archivos absolutas a las imágenes y escribirlas en el HTML. Mi HTML se genera usando una transformación XSL de un XML de objetos serializados, así que tendré que jugar con algunos parámetros XSL, lo que tomará un poco más de tiempo ya que no estoy tan familiarizado con ellos.
Esto es lo que hacemos, aunque debo mencionar que utilizamos un navegador web personalizado para eliminar cosas tales como la capacidad de hacer clic derecho y ver el buen menú contextual de 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);
Básicamente, debe tener una ruta de imagen que tenga un URI de archivo, por ejemplo
<img src="file://ApplicationPath/images/myImage.gif">
Lo tengo resuelto.
Acabo de pasar el URL completo resuelto del directorio exe a la transformación XSL que contiene el resultado HTML con etiquetas de imagen:
XsltArgumentList lstArgs = new XsltArgumentList();
lstArgs.AddParam("absoluteRoot", string.Empty, Path.GetFullPath("."));
Luego acabo de ponerle un prefijo a todas las imágenes con el valor del parámetro:
<img src="{$absoluteRoot}/Images/SilkIcons/comment_add.gif" align="middle" border="0" />
Terminé usando algo que es básicamente lo mismo que sugirió Ken. Sin embargo, en lugar de agregar manualmente el prefijo del archivo, utilicé la clase UriBuilder para construir el URI completo con el protocolo "file".
Esto también resolvió un problema posterior cuando probamos la aplicación en una ubicación más realista, Archivos de programa. Los espacios estaban codificados, pero el sistema operativo no podía tratar con los caracteres codificados cuando se hacía referencia al archivo utilizando una ruta de sistema estándar (es decir, "C: / Program% 20Files ..."). Usar el verdadero valor de URI (archivo: /// C: / Archivos de programa / ...) funcionó.
Alternativamente, mantenga sus enlaces relativos de estilo normal, suelte el código de transformación HTML y en su lugar incruste un servidor web C # como este en su exe, luego apunte su WebControl a su URL interna, como localhost: 8199 / myapp /
Al código de Ken le faltaban algunas cosas que necesitaba para funcionar. Lo revisé y creé un nuevo método que debería automatizar un poco las cosas.
Simplemente llame al método estático así:
html = HtmlFormatter.ReplaceImagePathAuto(html);
y todos los enlaces en html que coincidan con file: // ApplicationPath / se intercambiarán con el directorio de trabajo actual. Si desea especificar una ubicación alternativa, se incluye el método estático original (más los bits que le faltaron).
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);
}
}