Как мне сослаться на локальный ресурс в сгенерированном HTML в элементе управления WinForms WebBrowser?

Я использую элемент управления веб-браузера winforms для отображения некоторого содержимого в приложении Windows Forms. Я использую свойство DocumentText для записи сгенерированного HTML. Эта часть работает потрясающе. Теперь я хочу использовать в разметке несколько изображений. (Я также предпочел бы использовать связанные CSS и JavaScript, однако это можно обойти, просто встроив их.)

Я гуглил в течение нескольких дней и не могу найти ответа на вопрос, связанный с заголовком.

Я пробовал использовать относительную ссылку: приложение exe находится в bin \ debug. Изображения находятся в каталоге «Images» в корне проекта. Я установил, что изображения будут скопированы в выходной каталог при компиляции, поэтому они попадают в bin \ debug \ Images *. Затем я использую ссылку типа «Изображения ...», думая, что она будет относиться к exe. Однако, когда я смотрю на свойства изображения во встроенном окне браузера, я вижу, что URL-адрес изображения выглядит как «about: blankImages / *». Кажется, что все относительно "about: blank", когда HTML записывается в элемент управления. Не имея контекста местоположения, я не могу понять, что использовать для относительной ссылки на файловый ресурс.

Я покопался в свойствах элемента управления, чтобы посмотреть, есть ли способ установить что-нибудь, чтобы это исправить. Я создал пустую html-страницу и указал браузеру на нее с помощью метода «Navigate ()», используя полный локальный путь к файлу. Это нормально работало, когда браузер сообщал локальный путь "file: /// ..." к пустой странице. Затем я снова написал в браузер, на этот раз используя Document.Write (). Опять же, браузер теперь сообщает «about: blank» в качестве URL-адреса.

Если не записывать результаты динамического HTML в реальный файл, нет ли другого способа ссылаться на файловый ресурс?

Я собираюсь попробовать еще кое-что: построить абсолютные пути к файлам к изображениям и записать их в HTML. Мой HTML-код создается с использованием XSL-преобразования XML-сериализованного объекта, поэтому мне нужно поиграть с некоторыми XSL-параметрами, что потребует немного больше времени, поскольку я не очень хорошо с ними знаком.


person Peter    schedule 16.09.2008    source источник


Ответы (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">
person Ken Wootton    schedule 16.09.2008
comment
Встроенный веб-браузер можно настроить так, чтобы не отображать обычное контекстное меню: IsWebBrowserContextMenuEnabled = false - person Peter; 16.09.2008
comment
OOI PATH_SEPARATOR уже определен во фреймворке - Path.AltDirectorySeparatorChar - person Fraser; 03.12.2012

Я понял это.

Я просто передаю полный разрешенный URL-адрес каталога exe в преобразование XSL, которое содержит вывод HTML с тегами изображений:

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

Затем я просто снабдил все изображения префиксом значением параметра:

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

В итоге я использовал то, что в основном предлагал Кен. Однако вместо того, чтобы вручную добавлять префикс файла, я использовал класс UriBuilder для создания полного URI с протоколом «файл».

Это также решило последующую проблему, когда мы тестировали приложение в более реалистичном месте, Program Files. Пробелы были закодированы, но ОС не могла работать с закодированными символами, когда на файл ссылались с использованием стандартного системного пути (например, «C: \ Program% 20Files ...»). Использование истинного значения URI (file: /// C: / Program Files / ...) сработало.

person Peter    schedule 16.10.2008

В качестве альтернативы можно сохранить относительные ссылки в обычном стиле, отказаться от кода преобразования HTML и вместо этого встроить веб-сервер C #, например this в вашем exe, затем укажите свой WebControl на свой внутренний URL-адрес, например localhost: 8199 / myapp /

person Roark Fan    schedule 07.11.2008

В коде Кена не хватало нескольких вещей, необходимых для работы. Я пересмотрел его и создал новый метод, который должен немного автоматизировать.

Просто вызовите статический метод так:

html = HtmlFormatter.ReplaceImagePathAuto(html);

и все ссылки в html, соответствующие file: // 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);
    }
}
person Community    schedule 20.05.2009