从你的应用中共享内容 - 集成 Windows 共享功能

Windows共享表是一个系统提供的 UI,允许用户将内容从应用发送到其他Windows应用。 本指南介绍如何跨打包的应用(MSIX)、渐进式Web 应用(PWA)和未打包的 Win32 应用实现共享协定。

在本文中

Section 你将找到的内容
选择共享方法 为 UWP、桌面或 PWA 应用选择正确的 API 集
为 UWP 应用实现共享 DataTransferManager.GetForCurrentViewShowShareUI
为 PWA 实现分享功能 Web Share API 集成
为桌面应用实现共享 IDataTransferManagerInteropWinUI 3、WPF、WinForms 的按窗口共享
源端事件 观察目标选择、完成和取消
共享最佳做法 关于源端可靠行为的建议

选择共享方法

应用类型 Approach API 集合
UWP 应用 使用 DataTransferManager.GetForCurrentViewShowShareUI 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 应用。 在桌面应用中,如前所示获取 DataTransferManagerIDataTransferManagerInterop.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.OperationCompletedDataPackage.Destroyed 主要用于剪贴板和粘贴工作流。 共享源方案通常不需要它们。

共享最佳做法

使用此清单可预测源端行为。

推荐 避免 它为何重要
使用 SetWebLinkSetApplicationLink 用于 URL 对 URL 使用 SetText 链接在目标应用中可正确呈现并跳转
设置 Title 和可选元数据(Description、缩略图) 发送不含元数据的内容 改进共享界面的清晰度和目标渲染效果
如果您需要遥测功能,请处理 TargetApplicationChosenShareCompletedShareCanceled 假设这些信号来自源应用程序中的 ShareOperation 这些是用于分享后洞察的源侧信号
确保共享有效负载聚焦且适用于所选操作 默认发送不相关或过大的负载 减少失败并提高分享成功率