Предоставление общего доступа к содержимому из приложения — интеграция Windows Share

Лист общего доступа Windows — это системный пользовательский интерфейс, позволяющий пользователям отправлять содержимое из приложения в другие приложения Windows. В этом руководстве описывается, как реализовать контракт общего доступа для упакованных приложений (MSIX), прогрессивных веб-приложений (PWA) и неупакованных приложений Win32.

Секция Что вы найдете
Выбор подхода к совместному использованию Выбор подходящего набора API для приложений UWP, настольных приложений или PWA
Реализация функции "Поделиться" в приложениях UWP DataTransferManager.GetForCurrentView и ShowShareUI.
Реализовать функцию «Поделиться» для PWA Интеграция с Web Share API
Реализация общего доступа для классических приложений IDataTransferManagerInteropобщий доступ к окнам для WinUI 3, WPF, WinForms
События на стороне источника Отслеживать выбор целевого объекта, завершение и отмену
Рекомендации по совместному использованию Рекомендации по надежному поведению на стороне источника

Выбор подхода к совместному использованию

Тип приложения Approach Набор интерфейсов API
Приложения UWP Использование DataTransferManager.GetForCurrentView и ShowShareUI Windows.ApplicationModel.DataTransfer
Настольные приложения (WinUI 3, WPF, WinForms) Используйте IDataTransferManagerInterop для совместного использования отдельных окон (в упакованных и неупакованных приложениях) среда выполнения Windows посредством COM-взаимодействия
Прогрессивные веб-приложения (PWA) Использование API веб-общего доступа и интеграции Windows W3C Web Share

Реализация функции «Поделиться» в приложениях 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. Отображение пользовательского интерфейса общего доступа

Вызвать меню «Поделиться» нажатием кнопки или командой меню:

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();
}

Реализуйте функцию Share для прогрессивных веб-приложений (PWA)

PWA используют Web Share API от W3C. Убедитесь, что У PWA есть необходимые свойства манифеста для интеграции с Windows:

{
  "name": "My PWA",
  "short_name": "MyPWA",
  "share_target": {
    "action": "/share",
    "method": "POST",
    "enctype": "multipart/form-data",
    "params": {
      "files": [
        {
          "name": "media",
          "accept": ["image/*"]
        }
      ]
    }
  }
}

В JavaScript-коде вашего PWA используйте Web Share 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 Share Source.

События на стороне источника

Используйте эти события в исходных приложениях, чтобы наблюдать за тем, что произошло после того, как пользователь откроет общий доступ.

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.OperationCompleted и DataPackage.Destroyed в первую очередь предназначены для рабочих процессов буфера обмена и вставки. Как правило, они не нужны для сценариев источника Share.

Рекомендации по использованию Share

Используйте этот контрольный список для обеспечения предсказуемости поведения на стороне источника.

Рекомендуется Избегайте Почему это важно
Используйте SetWebLink или SetApplicationLink для URL-адресов Используйте SetText для URL-адресов Ссылки правильно отображаются и ведут в нужные места в целевых приложениях
Задать Title и необязательные метаданные (Description, эскиз) Отправка содержимого без метаданных Повышает понятность интерфейса обмена и улучшает отображение целевого объекта
Обрабатывайте TargetApplicationChosen, ShareCompleted и ShareCanceled, если вам нужна телеметрия Предполагая, что эти сигналы исходят из ShareOperation исходных приложений Это сигналы на стороне источника для аналитики после публикации
Сохраняйте общие полезные нагрузки целенаправленными и корректными для выбранного действия Отправка по умолчанию несвязанных или слишком больших объёмов данных Снижает количество сбоев и повышает скорость успешности общего доступа