C# Winform中 webView2加载内嵌程序集资源 都有什么方法

C# Winform中 webView2加载内嵌程序集资源 都有什么方法

我目前研究到一种,但是这个办法欠妥当,寻求其他方式。

以下是我研究的方法

img

img


            string objdata = string.Empty;
            using (var sm = typeof(Form1).Assembly.GetManifestResourceStream("测试view2.Res.index.html"))
            {
                var data = new byte[sm.Length];
                sm.Read(data, 0, data.Length);
                objdata = Encoding.UTF8.GetString(data);
            }
            webView21.CoreWebView2.NavigateToString(objdata);

1.可以将内部件映射到虚拟路径上
官方文档说明
https://github.com/MicrosoftEdge/WebView2Feedback/blob/main/specs/HostResourceMapping.md
例子是将本地一个目录映射到虚拟域名上

2.你是内嵌资源不是本地目录,不过没有啥关系。我们依旧可以“虚拟映射”
nuget:Microsoft.Extensions.FileProviders.Embedded
我们给自己的程序系统加个虚拟的嵌入文件提供就行

你也可以如官方这样,直接指定一个虚拟域名,然后对这个虚拟域名的资源访问进行拦截处理

https://github.com/MicrosoftEdge/WebView2Feedback/blob/main/specs/WebResourceRequested-CustomScheme.md

在C# Winform中使用webView2控件加载内嵌程序集资源的方法有以下几种:

  1. 使用WebResource.axd的方式加载内嵌资源

这种方式需要在Web.config中配置一个HttpHandler处理程序,并在WebView2控件中通过JavaScript调用该处理程序,例如:

using System;
using System.Reflection;
using System.Web;

namespace Demo {
    public class MyHttpHandler : IHttpHandler {
        public void ProcessRequest(HttpContext context) {
            string resourceName = context.Request.QueryString["resource"];
            if (!string.IsNullOrEmpty(resourceName)) {
                byte[] bytes = GetResourceBytes(resourceName);
                if (bytes != null) {
                    context.Response.ContentType = GetMimeType(resourceName);
                    context.Response.OutputStream.Write(bytes, 0, bytes.Length);
                    context.Response.Flush();
                }
            }
        }
 
        public bool IsReusable {
            get { return false; }
        }
         
        // 获取内嵌资源的字节数组
        private static byte[] GetResourceBytes(string resourceName) {
            Assembly assembly = Assembly.GetExecutingAssembly();
            string[] resourceNames = assembly.GetManifestResourceNames();
            string resourceNameFull = resourceNames.FirstOrDefault(r => r.EndsWith(resourceName));
            if (!string.IsNullOrEmpty(resourceNameFull)) {
                using (Stream stream = assembly.GetManifestResourceStream(resourceNameFull)) {
                    if (stream != null) {
                        byte[] bytes = new byte[stream.Length];
                        stream.Read(bytes, 0, bytes.Length);
                        return bytes;
                    }
                }
            }
            return null;
        }
 
        // 获取内嵌资源的MIME类型
        private static string GetMimeType(string resourceName) {
            string extension = Path.GetExtension(resourceName).ToLower();
            switch (extension) {
                case ".htm":
                case ".html":
                    return "text/html";
                case ".css":
                    return "text/css";
                case ".js":
                    return "text/javascript";
                case ".png":
                    return "image/png";
                case ".gif":
                    return "image/gif";
                case ".jpg":
                case ".jpeg":
                    return "image/jpeg";
                case ".ico":
                    return "image/x-icon";
                default:
                    return "application/octet-stream";
            }
        }
    }
}

然后在WebView2控件中使用JavaScript代码调用该处理程序,例如:

string resourceUrl = string.Format("http://{0}/{1}", "localhost:1234", "WebResource.axd?resource=style.css");
string jsCode = string.Format("var cssLink = document.createElement('link'); cssLink.rel = 'stylesheet'; cssLink.href = '{0}'; document.head.appendChild(cssLink);", resourceUrl);
webView2.CoreWebView2.ExecuteScriptAsync(jsCode);
  1. 使用WebBrowser控件加载内嵌资源

如果已经存在WebBrowser控件,也可以使用该控件加载内嵌资源,例如:

webBrowser.ObjectForScripting = new ObjectForScripting();
webBrowser.Navigate("about:blank");
webBrowser.Document.OpenNew(false);
string html = "<html><head><title> Demo </title><style>";
html += GetResourceContent("Demo.Form1.style.css");
html += "</style></head><body></body></html>";
webBrowser.Document.Write(html);

其中,GetResourceContent方法用于获取内嵌资源的内容,例如:

private string GetResourceContent(string resourceName) {
    Assembly assembly = Assembly.GetExecutingAssembly();
    string[] resourceNames = assembly.GetManifestResourceNames();
    string resourceNameFull = resourceNames.FirstOrDefault(r => r.EndsWith(resourceName));
    if (!string.IsNullOrEmpty(resourceNameFull)) {
        using (Stream stream = assembly.GetManifestResourceStream(resourceNameFull)) {
            if (stream != null) {
                using (StreamReader reader = new StreamReader(stream)) {
                    return reader.ReadToEnd();
                }
            }
        }
    }
    return null;
}

以上是两种比较常用的加载内嵌程序集资源的方法,根据实际需求进行选择。