2016-03-13 7 views
1

И использование SchemeHandler CefSharp для того, чтобы захватить ресурсы из моего C# проекта, как .css, .js или .png файлы, используя пользовательский URL, например custom://cefsharp/assets/css/style.cssCefSharp пользовательского SchemeHandler

Я 2 пользовательских классы для того, чтобы заархивировать это.

Первый класс, MyCustomSchemeHandlerFactory будет один, который обрабатывает пользовательские схемы и это выглядит, где «обычай» будет принято схема:

internal class MyCustomSchemeHandlerFactory : ISchemeHandlerFactory 
{ 
    public const string SchemeName = "custom"; 

    public IResourceHandler Create(IBrowser browser, IFrame frame, string schemeName, IRequest request) 
    { 
     return new MyCustomSchemeHandler(); 
    } 
} 

Следующий класс я реализовал это MyCustomSchemeHandler который получит вызов и вывести ответ и это выглядит следующим образом:

internal class MyCustomSchemeHandler : IResourceHandler 
{ 

    private static readonly IDictionary<string, string> ResourceDictionary; 

    private string mimeType; 
    private MemoryStream stream; 

    static MyCustomSchemeHandler() 
    { 
     ResourceDictionary = new Dictionary<string, string> 
     { 
      { "/home.html", Properties.Resources.index}, 
      { "/assets/css/style.css", Properties.Resources.style} 
     }; 
    } 

    public Stream Stream { get; set; } 
    public int StatusCode { get; set; } 
    public string StatusText { get; set; } 
    public string MimeType { get; set; } 
    public NameValueCollection Headers { get; private set; } 

    public Stream GetResponse(IResponse response, out long responseLength, out string redirectUrl) 
    { 
     redirectUrl = null; 
     responseLength = -1; 

     response.MimeType = MimeType; 
     response.StatusCode = StatusCode; 
     response.StatusText = StatusText; 
     response.ResponseHeaders = Headers; 

     var memoryStream = Stream as MemoryStream; 
     if (memoryStream != null) 
     { 
      responseLength = memoryStream.Length; 
     } 

     return Stream; 
    } 

    public bool ProcessRequestAsync(IRequest request, ICallback callback) 
    { 
     // The 'host' portion is entirely ignored by this scheme handler. 
     var uri = new Uri(request.Url); 
     var fileName = uri.AbsolutePath; 
     string resource; 

     if (ResourceDictionary.TryGetValue(fileName, out resource) && !string.IsNullOrEmpty(resource)) 
     { 
      var resourceHandler = ResourceHandler.FromString(resource); 
      stream = (MemoryStream)resourceHandler.Stream; 

      var fileExtension = Path.GetExtension(fileName); 
      mimeType = ResourceHandler.GetMimeType(fileExtension); 

      callback.Continue(); 
      return true; 
     } 
     else 
     { 
      callback.Dispose(); 
     } 

     return false; 
    } 

    void GetResponseHeaders(IResponse response, out long responseLength, out string redirectUrl) 
    { 
     responseLength = stream == null ? 0 : stream.Length; 
     redirectUrl = null; 

     response.StatusCode = (int)HttpStatusCode.OK; 
     response.StatusText = "OK"; 
     response.MimeType = mimeType; 
    } 

    bool ReadResponse(Stream dataOut, out int bytesRead, ICallback callback) 
    { 
     //Dispose the callback as it's an unmanaged resource, we don't need it in this case 
     callback.Dispose(); 

     if (stream == null) 
     { 
      bytesRead = 0; 
      return false; 
     } 

     //Data out represents an underlying buffer (typically 32kb in size). 
     var buffer = new byte[dataOut.Length]; 
     bytesRead = stream.Read(buffer, 0, buffer.Length); 

     dataOut.Write(buffer, 0, buffer.Length); 

     return bytesRead > 0; 
    } 

    bool CanGetCookie(Cookie cookie) 
    { 
     return true; 
    } 

    bool CanSetCookie(Cookie cookie) 
    { 
     return true; 
    } 

    void Cancel() 
    { 

    } 

} 

Внутри этого класса я определил пользовательский словарь ресурсов, который будет диктовать, какой файл из ресурсов будет использоваться, так как я уже говорил в первый пример, custom://cefsharp/assets/css/style.css должен загрузить ресурс Properties.Resources.style, проблема в том, что ничто не загружается после ввода определенного URL-адреса, я пытался вывести mimeType, и он работает, но каким-то образом сам файл будет выводиться неправильно. Что-то не так с моей реализацией?

Additionaly Я пытался выводить необработанный файл в виде:

if (ResourceDictionary.TryGetValue(fileName, out resource) && !string.IsNullOrEmpty(resource)) 
{ 
    MessageBox.Show(resource); 
} 

И выводит правильный файл без каких-либо проблем.

Для загрузки пользовательской схемы я использую следующий код перед инициализацией CefSharp:

var settings = new CefSettings(); 
settings.RegisterScheme(new CefCustomScheme 
{ 
    SchemeName = MyCustomSchemeHandlerFactory.SchemeName, 
    SchemeHandlerFactory = new MyCustomSchemeHandlerFactory() 
}); 

Вышеуказанные классы были основаны на следующих ссылках: MyCustomSchemeHandlerFactory: FlashResourceHandlerFactory.cs MyCustomSchemeHandler: CefSharpSchemeHandler.cs и ResourceHandler.cs

+0

Используйте примеры из ветви, соответствующие вашей версии, если вы используете '47.0.3', затем используйте ветку' cefsharp/47', те, что от 'master', не будут работать до тех пор, пока не будет выпущено' 49.0.0' , https://github.com/cefsharp/CefSharp/tree/cefsharp/47 – amaitland

ответ

1

Если вам просто нужно вернуть строку, тогда вы можете использовать ResourceHandler.FromString(html, mimeType). Для этого вам просто нужно реализовать ISchemeHandlerFactory.

https://github.com/cefsharp/CefSharp/blob/cefsharp/47/CefSharp/ResourceHandler.cs#L98

Пример чтения из файла https://github.com/cefsharp/CefSharp/blob/cefsharp/47/CefSharp.Example/CefSharpSchemeHandlerFactory.cs#L17, который может быть переведен на чтение из строки довольно просто.