可以使用 URL 提供的 HTML 填充Windows小组件,而不是使用自适应卡片定义其正文。 提供程序仍提供指定内容 URL 的自适应卡片 JSON 有效负载。 首先使用在 C# Windows 应用 中实现小组件提供程序或在 win32 应用(C++/WinRT)中实现小组件提供程序,然后添加此处所述的 Web 内容功能。
本文中的资源和消息传送 API 是在 Windows 应用 SDK 1.6.3 中引入的。 使用Windows 应用 SDK发布通道中当前支持的稳定版本,并在支持 Web 内容的小组件主机的 Windows 11 设备上进行测试。
C# 示例是打包的桌面小组件提供程序的片段。 将 using Microsoft.Windows.Widgets.Providers; 和 using Windows.Storage.Streams; 添加到提供程序的源文件中。 添加 IWidgetResourceProvider 或 IWidgetProviderMessage 时,继续实现 IWidgetProvider。
指定内容 URL
使用 WidgetManager.UpdateWidget 发送 JSON 有效负载。 使用指向 HTML 内容的 webUrl 字段指定 元数据 对象。 包括自适应卡片 正文 作为不支持加载 Web 内容的主机的回退内容,而不是将这些主机保留为空小组件。
{
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.6",
"body": [
{
"type": "TextBlock",
"text": "Open the app to view this content.",
"wrap": true
}
],
"metadata": {
"webUrl": "https://contoso.com/widgetprovider.html"
}
}
$host.isWebSupported 模板属性指示主机是否支持 Web 内容。 如果需要进一步调整后备呈现,请使用它。 有关详细信息,请参阅Windows小组件主机属性。
处理资源请求
小组件提供程序可以在提供程序的包清单文件的 Definition 元素的 WebRequestFilter 特性中为小组件指定 Web 请求筛选字符串。 每当小组件内容通过与筛选器匹配的 URI 请求资源时,都会截获请求并将其重定向到小组件提供程序的 IWidgetResourceProvider.OnResourceRequested 实现。
筛选器模式使用 匹配模式中所述的格式。 如有必要,请使用 Punycode 。 筛选器必须与 WebUrl 指定的原点匹配。 所有内容类型的请求在匹配时会重定向,因此将筛选器限制为提供程序处理的资源。 有关详细信息,请参阅 Widget 提供程序包清单 XML 格式。
若要处理资源请求,小组件提供程序必须实现 IWidgetResourceProvider 接口。
internal class WidgetProvider : IWidgetProvider, IWidgetResourceProvider
在 OnResourceRequested 中,将 WidgetResourceRequestedArgs.Response 设置为包含资源的 WidgetResourceResponse 。 此示例将一个请求的 URL 映射到打包的图像。 在应用包中将 Assets\image.png 作为内容包含在内。 RandomAccessStreamReference.CreateFromUri 支持 ms-appx 方案,因此无需等待文件查找即可创建流引用。
void IWidgetResourceProvider.OnResourceRequested(WidgetResourceRequestedArgs args)
{
if (args.Request.Uri == "https://contoso.com/logo-image")
{
var imageUri = new System.Uri("ms-appx:///Assets/image.png");
var content = RandomAccessStreamReference.CreateFromUri(imageUri);
var response = new WidgetResourceResponse(content, "OK", 200);
response.Headers.Add("Content-Type", "image/png");
args.Response = response;
}
}
此同步示例不需要延迟。 如果实现在设置响应之前需要等待操作完成,请在回调返回之前调用 GetDeferral,并在 finally 块中将其完成。 根据应用的错误处理策略处理和报告异步失败。
如果未设置响应,系统会从 Web 检索资源。 可以在发起该次提取之前,在 args.Request 上修改 WidgetResourceRequest.Headers。 仅向你信任的源请求添加凭据;仅凭筛选器匹配并不能授权发送令牌。
处理与 Web 内容之间的消息
若要从已使用 window.chrome.webview.postMessage JavaScript 方法发布的小组件内容接收字符串消息,小组件提供程序可以实现 IWidgetProviderMessage 接口并实现 OnMessageReceived 方法。
internal class WidgetProvider : IWidgetProvider, IWidgetProviderMessage
将回调添加到提供程序类:
public void OnMessageReceived(WidgetMessageReceivedArgs args)
{
System.Console.WriteLine($"Message received from widget {args.WidgetContext.Id}: {args.Message}");
}
使用 WidgetManager.SendMessageToContent 将消息发送到小组件的 Web 内容。 从 WidgetContext.Id 传递小组件实例 ID,而不是包清单中的定义 ID。 一个定义的多个实例具有不同的实例 ID。
从提供程序回调中调用以下帮助程序,为目标实例传递 WidgetContext,例如 CreateWidget 或 OnActionInvoked 收到的上下文。 序列化结构化消息,而不是使用字符串内插构造 JSON,因此包含引号或反斜杠的值仍然有效。
private static void SendLocationToWidget(WidgetContext widgetContext, string location)
{
string message = System.Text.Json.JsonSerializer.Serialize(
new { current_location = location });
WidgetManager.GetDefault().SendMessageToContent(widgetContext.Id, message);
}
Web 内容通过 window.chrome.webviewmessage 事件以字符串的形式接收消息。 如果按此示例所示序列化 JSON,请在您的网页内容中解析该字符串。 有关详细信息,请参阅 PostWebMessageAsString 和 WebView2 JavaScript API。
限制和要求
Important
此功能仅适用于欧盟经济区(OEC)中的用户。
相关实现路径
Web 小组件提供程序不是 Feed 提供程序。 有关仪表板源及其区域要求,请参阅 仪表板和提要提供程序。 有关单独的 PWA 清单和 Service Worker 实现路径,请参阅 构建 PWA 驱动的微件。