Windows共享表是一个系统提供的 UI,允许用户将内容从应用发送到其他Windows应用。 本指南介绍如何跨打包的应用(MSIX)、渐进式Web 应用(PWA)和未打包的 Win32 应用实现共享协定。
在本文中
| Section | 你将找到的内容 |
|---|---|
| 选择共享方法 | 为 UWP、桌面或 PWA 应用选择正确的 API 集 |
| 为 UWP 应用实现共享 |
DataTransferManager.GetForCurrentView 和 ShowShareUI |
| 为 PWA 实现分享功能 | Web Share API 集成 |
| 为桌面应用实现共享 |
IDataTransferManagerInteropWinUI 3、WPF、WinForms 的按窗口共享 |
| 源端事件 | 观察目标选择、完成和取消 |
| 共享最佳做法 | 关于源端可靠行为的建议 |
选择共享方法
| 应用类型 | Approach | API 集合 |
|---|---|---|
| UWP 应用 | 使用 DataTransferManager.GetForCurrentView 和 ShowShareUI |
Windows.ApplicationModel.DataTransfer |
| 桌面应用(WinUI 3、WPF、WinForms) | 用于 IDataTransferManagerInterop 每窗口共享(打包或解压缩) |
通过 COM 互操作使用 Windows 运行时 |
| 渐进式 Web 应用 (PWA) | 使用 Web Share API 和 Windows 集成 | W3C Web 共享 |
为 UWP 应用实现共享
Important
DataTransferManager.GetForCurrentView 并且 ShowShareUI 仅在 UWP 应用中受支持。 桌面应用(WinUI 3、WPF 或 WinForms - 打包或解压缩)必须使用IDataTransferManagerInterop“实现共享”中显示的桌面应用模式。
1. 获取 DataTransferManager
在页面初始化时,获取对 DataTransferManager 的引用:
using Windows.ApplicationModel.DataTransfer;
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
DataTransferManager dtm = DataTransferManager.GetForCurrentView();
dtm.DataRequested += OnDataRequested;
}
}
2. 填充 DataPackage
当用户启动共享(例如,单击“共享”按钮)时,请使用内容和元数据创建一个 DataPackage :
private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
DataRequest request = args.Request;
DataPackage data = request.Data;
// Set a title (required)
data.Properties.Title = "My shared content";
// Set content - choose one or more:
data.SetText("Here's some text to share");
// For URLs, use SetWebLink to enable rich link previews:
// data.SetWebLink(new Uri("https://example.com"));
// For files or images:
// IStorageItem item = await StorageFile.GetFileFromPathAsync(filePath);
// data.SetStorageItems(new[] { item });
// Optional: add description and thumbnail
data.Properties.Description = "A brief description";
// data.Properties.Thumbnail = /* RandomAccessStreamReference */;
}
Tip
共享 URL 时,请使用 SetWebLink (或 SetApplicationLink 用于深层链接)而不是 SetText。 然后,目标应用可以生成丰富的链接预览并正确处理导航,而不是将其视为纯文本。
3.显示共享 UI
通过点击按钮或执行菜单命令来触发共享表单:
private void ShareButton_Click(object sender, RoutedEventArgs e)
{
// ShowShareUI is a static method on DataTransferManager.
// The DataRequested handler was registered in step 1.
DataTransferManager.ShowShareUI();
}
为渐进式 Web 应用(PWA)实现分享功能
PWA 使用 W3C Web 共享 API。 确保 PWA 具有与Windows集成的所需清单属性:
{
"name": "My PWA",
"short_name": "MyPWA",
"share_target": {
"action": "/share",
"method": "POST",
"enctype": "multipart/form-data",
"params": {
"files": [
{
"name": "media",
"accept": ["image/*"]
}
]
}
}
}
在 PWA JavaScript 中,使用 Web 共享 API:
async function shareContent() {
if (navigator.share) {
try {
await navigator.share({
title: 'Check this out',
text: 'Great content',
url: 'https://example.com/page'
});
} catch (err) {
if (err.name !== 'AbortError') {
console.error('Share failed:', err);
}
}
}
}
实现桌面应用的共享(WinUI 3、WPF、WinForms)
桌面应用(无论是打包的还是未打包的)都使用 IDataTransferManagerInterop 接口按窗口访问共享面板。 这适用于 WinUI 3、WPF 和 WinForms 应用。
1. 声明互操作接口并获取 DataTransferManager
using Windows.ApplicationModel.DataTransfer;
[System.Runtime.InteropServices.ComImport]
[System.Runtime.InteropServices.Guid("3A3DCD6C-3EAB-43DC-BCDE-45671CE800C8")]
[System.Runtime.InteropServices.InterfaceType(
System.Runtime.InteropServices.ComInterfaceType.InterfaceIsIUnknown)]
interface IDataTransferManagerInterop
{
IntPtr GetForWindow([System.Runtime.InteropServices.In] IntPtr appWindow,
[System.Runtime.InteropServices.In] ref Guid riid);
void ShowShareUIForWindow(IntPtr appWindow);
}
public sealed partial class MainWindow // WinUI 3 Window, WPF Window, or WinForms Form
{
// IID of DataTransferManager, passed as the riid to GetForWindow:
static readonly Guid _dtm_iid =
new Guid(0xa5caee9b, 0x8708, 0x49d1, 0x8d, 0x36, 0x67, 0xd2, 0x5a, 0x8d, 0xa0, 0x0c);
private DataTransferManager _dtm;
// Call this from your window or form constructor (or load handler):
private void InitializeShare()
{
// Retrieve the window handle (HWND) for the current window:
// WinUI 3: IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
// WPF: IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
// WinForms: IntPtr hWnd = this.Handle;
IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
IDataTransferManagerInterop interop =
DataTransferManager.As<IDataTransferManagerInterop>();
_dtm = WinRT.MarshalInterface<DataTransferManager>.FromAbi(
interop.GetForWindow(hWnd, _dtm_iid));
_dtm.DataRequested += (sender, args) => OnDataRequested(args);
}
}
2. 填入并显示
private void OnDataRequested(DataRequestedEventArgs args)
{
DataRequest request = args.Request;
DataPackage data = request.Data;
data.Properties.Title = "Share from my desktop app";
data.SetText("Shared content");
// For URLs:
// data.SetWebLink(new Uri("https://example.com"));
// For files:
// var item = await StorageFile.GetFileFromPathAsync(filePath);
// data.SetStorageItems(new[] { item });
}
// In your Share button handler:
private void ShareButton_Click()
{
var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
var interop = DataTransferManager.As<IDataTransferManagerInterop>();
interop.ShowShareUIForWindow(hWnd);
}
有关完整示例,请参阅WPF共享源示例。
源端事件
在源应用中使用这些事件观察用户打开“共享”后发生的情况。
| API | 当它触发时 | 使用原因 |
|---|---|---|
DataTransferManager.DataRequested |
用户启动共享操作 | 生成并附加 DataPackage |
DataTransferManager.TargetApplicationChosen |
用户选择目标应用 | 用于目标选择的可选遥测 |
DataPackage.ShareCompleted |
共享已完成 | 可选成功遥测 |
DataPackage.ShareCanceled |
用户取消共享 | 可选取消遥测数据 |
注释
本示例为简洁起见使用 GetForCurrentView,这适用于 UWP 应用。 在桌面应用中,如前所示获取 DataTransferManager 到 IDataTransferManagerInterop.GetForWindow,然后绑定相同的事件。
private void RegisterShareEvents()
{
var dtm = DataTransferManager.GetForCurrentView();
dtm.DataRequested += OnDataRequested;
dtm.TargetApplicationChosen += OnTargetChosen;
}
private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
DataRequest request = args.Request;
request.Data.Properties.Title = "Share from my app";
request.Data.SetText("Hello from Windows Share");
request.Data.ShareCompleted += OnShareCompleted;
request.Data.ShareCanceled += OnShareCanceled;
}
private void OnTargetChosen(DataTransferManager sender, TargetApplicationChosenEventArgs args)
{
// Optional: telemetry only
Debug.WriteLine($"Target app: {args.ApplicationName}");
}
private void OnShareCompleted(DataPackage sender, ShareCompletedEventArgs args)
{
Debug.WriteLine("Share completed");
}
private void OnShareCanceled(DataPackage sender, object args)
{
Debug.WriteLine("Share canceled");
}
注释
DataPackage.OperationCompleted 和 DataPackage.Destroyed 主要用于剪贴板和粘贴工作流。 共享源方案通常不需要它们。
共享最佳做法
使用此清单可预测源端行为。
| 推荐 | 避免 | 它为何重要 |
|---|---|---|
使用 SetWebLink 或 SetApplicationLink 用于 URL |
对 URL 使用 SetText |
链接在目标应用中可正确呈现并跳转 |
设置 Title 和可选元数据(Description、缩略图) |
发送不含元数据的内容 | 改进共享界面的清晰度和目标渲染效果 |
如果您需要遥测功能,请处理 TargetApplicationChosen、ShareCompleted 和 ShareCanceled。 |
假设这些信号来自源应用程序中的 ShareOperation |
这些是用于分享后洞察的源侧信号 |
| 确保共享有效负载聚焦且适用于所选操作 | 默认发送不相关或过大的负载 | 减少失败并提高分享成功率 |