Terima konten di aplikasi - integrasikan fitur Berbagi Windows

Lembar Berbagi Windows memungkinkan Anda menerima konten (dibagikan dari aplikasi lain) melalui aplikasi Anda. Panduan ini menjelaskan cara mendaftarkan aplikasi Anda sebagai Target Berbagi dan menangani konten bersama di seluruh aplikasi paket (MSIX), Progressive Web Apps (PWAs), dan aplikasi Win32 yang tidak dikemas.

Bagian Apa yang akan Anda temukan
Sebelum Anda mendeklarasikan kemampuan Nyatakan hanya jenis file dan format yang ditangani aplikasi Anda
Menerapkan target berbagi untuk aplikasi terkemas (UWP dan aplikasi desktop terkemas) Deklarasi manifes dan penanganan aktivasi untuk aplikasi UWP dan aplikasi desktop yang dipaketkan
Menerapkan Target Berbagi untuk PWAs share_target manifest dan penanganan POST
Menerima konten yang dibagikan di aplikasi Win32 tanpa paket Berikan identitas paket dan daftarkan sebagai target berbagi
Praktik terbaik Rekomendasi untuk alur penerimaan yang andal
Laporkan kemajuan penerimaan Pelaporan status untuk pembagian berukuran besar atau yang berlangsung lama
Pemecahan masalah Perbaikan untuk masalah umum pada Share Target

Sebelum Anda mendeklarasikan kemampuan

Sebagian besar bug integrasi share target berasal dari mendeklarasikan kemampuan yang melebihi yang benar-benar bisa ditangani aplikasi Anda. Jika aplikasi Anda mendeklarasikan <uap:SupportsAnyFileType />, aplikasi akan muncul di Lembar Berbagi untuk setiap jenis file, termasuk file yang tidak dapat diproses (misalnya, editor foto muncul saat pengguna berbagi spreadsheet).

Selalu nyatakan hanya jenis file dan format data tertentu yang dapat ditangani aplikasi Anda. Contohnya:

<!-- ✓ Correct: declare only what you support -->
<uap:SupportedFileTypes>
  <uap:FileType>.jpg</uap:FileType>
  <uap:FileType>.png</uap:FileType>
</uap:SupportedFileTypes>

<!-- ✗ Incorrect: declares everything -->
<!-- <uap:SupportsAnyFileType /> -->

Sisakan <uap:SupportsAnyFileType /> hanya untuk aplikasi pemindah file umum (penyimpanan awan, aplikasi transfer file). Lihat Referensi DataFormat & FileType untuk deklarasi menurut kategori aplikasi.

Mengimplementasikan target berbagi untuk aplikasi yang dipaketkan (UWP dan desktop yang dipaketkan)

Bagian ini berlaku untuk aplikasi UWP dan aplikasi desktop paket (WinUI 3, WPF, WinForms). Keduanya dikirim sebagai paket MSIX dengan identitas paket, sehingga mereka mendeklarasikan Target Berbagi dengan cara yang sama dan hanya berbeda dalam cara mereka menangani aktivasi (ditunjukkan pada langkah 2).

1. Deklarasikan dalam manifes

Edit package.appxmanifest Anda untuk mendaftarkannya sebagai Target Berbagi. Nyatakan hanya jenis file dan format data yang ditangani aplikasi Anda:

<Extensions>
  <uap:Extension Category="windows.shareTarget">
    <uap:ShareTarget>
      <uap:SupportedFileTypes>
        <uap:FileType>.jpg</uap:FileType>
        <uap:FileType>.jpeg</uap:FileType>
        <uap:FileType>.png</uap:FileType>
        <uap:FileType>.gif</uap:FileType>
        <uap:FileType>.bmp</uap:FileType>
      </uap:SupportedFileTypes>
      <uap:DataFormat>Bitmap</uap:DataFormat>
    </uap:ShareTarget>
  </uap:Extension>
</Extensions>

2. Atasi aktivasi Bagikan

Saat aplikasi Anda diaktifkan sebagai target berbagi, tangani peristiwa OnShareTargetActivated:

Note

OnShareTargetActivated adalah penggantian aktivasi untuk aplikasi UWP (Windows.UI.Xaml.Application). Aplikasi desktop yang dipaketkan (WinUI 3, WPF, WinForms) menerima aktivasi bagikan melalui AppInstance.GetActivatedEventArgs dan memeriksa ExtendedActivationKind.ShareTarget. Lihat Mendapatkan info aktivasi untuk aplikasi paket.

protected override async void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
{
    ShareOperation shareOperation = args.ShareOperation;
    shareOperation.ReportStarted();

    try
    {
        if (shareOperation.Data.Contains(StandardDataFormats.StorageItems))
        {
            IReadOnlyList<IStorageItem> items = await shareOperation.Data.GetStorageItemsAsync();
            
            // Validate: check count, types, and sizes
            if (items.Count == 0)
            {
                shareOperation.ReportError("No items received.");
                return;
            }

            var file = (IStorageFile)items[0];
            
            // Process the file
            await ProcessImageAsync(file);
        }
        
        shareOperation.ReportCompleted();
    }
    catch (Exception ex)
    {
        shareOperation.ReportError($"Error: {ex.Message}");
    }
}

private async Task ProcessImageAsync(IStorageFile file)
{
    // Your processing logic here
}

Untuk aplikasi desktop terpaket (WinUI 3, WPF, WinForms) yang dibuat dengan SDK Aplikasi Windows, tidak ada penimpaan OnShareTargetActivated. Sebaliknya, periksa aktivasi di metode Main Anda dan periksa adanya ExtendedActivationKind.ShareTarget:

using Microsoft.Windows.AppLifecycle;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.DataTransfer;

[STAThread]
static void Main(string[] args)
{
    AppActivationArguments activatedArgs = AppInstance.GetCurrent().GetActivatedEventArgs();
    if (activatedArgs.Kind == ExtendedActivationKind.ShareTarget)
    {
        HandleShareAsync(activatedArgs.Data as ShareTargetActivatedEventArgs);
    }
    else
    {
        // Normal launch path
    }
}

static async void HandleShareAsync(ShareTargetActivatedEventArgs args)
{
    ShareOperation shareOperation = args.ShareOperation;
    shareOperation.ReportStarted();

    if (shareOperation.Data.Contains(StandardDataFormats.StorageItems))
    {
        IReadOnlyList<IStorageItem> items = await shareOperation.Data.GetStorageItemsAsync();
        // Process the shared items.
    }

    shareOperation.ReportCompleted();
}

3. Pilih format data apa yang akan dinyatakan

Gunakan referensi ini untuk memutuskan apa yang harus dinyatakan:

Format Kapan digunakan Contoh aplikasi
StorageItems Aplikasi Anda menerima file Editor foto, pembaca dokumen
Bitmap Aplikasi Anda menerima gambar Penampil gambar, aplikasi desain
Text Aplikasi Anda menerima teks biasa Aplikasi catatan, editor teks
Html Aplikasi Anda menerima konten teks kaya Klien email, editor teks kaya
Uri / WebLink Aplikasi Anda menangani tautan Browser, manajer tautan
Rtf Aplikasi Anda menerima teks berformat pengolah kata

Untuk detail selengkapnya, lihat Referensi DataFormat & FileType.

Menerapkan target berbagi untuk Aplikasi Web Progresif (PWA)

PWA di Windows terdaftar sebagai target berbagi melalui Manifes Aplikasi Web. Tambahkan entri share_target:

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

Pada rute /share Anda, tangani permintaan POST:

app.post('/share', async (req, res) => {
  const { title, text, url, files } = req.body;

  // Validate and process
  if (files && files.length > 0) {
    const file = files[0];
    // Process the file
    console.log('Received file:', file.originalname);
  }

  if (text) {
    console.log('Received text:', text);
  }

  res.redirect('/');
});

Hanya nyatakan jenis file yang dapat ditangani PWA Anda. Misalnya, jangan nyatakan * sebagai jenis terima kecuali aplikasi Anda benar-benar menangani semua file.

Menerima konten yang dibagikan dalam aplikasi Win32 tanpa paket

Untuk mendaftar sebagai Target Berbagi, aplikasi Anda memerlukan identitas paket. Jika aplikasi Win32 Anda tidak dikemas, berikan identitas paket dengan salah satu dari dua cara:

  • Kemas ulang dengan MSIX (lebih disukai): gunakan templat Project Kemasan Aplikasi Windows di Visual Studio untuk penginstalan yang bersih dan tepercaya. Lihat Menyiapkan aplikasi desktop Anda untuk kemasan MSIX.
  • Paket dengan lokasi eksternal (paket sparse): tambahkan paket MSIX kosong yang berisi identitas, registrasi target berbagi, dan aset visual, sementara penginstal yang sudah ada tetap mengelola biner aplikasi. Gunakan ini hanya ketika Anda memiliki alat penginstal, Anda tidak dapat pindah ke MSIX.

Bagian selanjutnya menjelaskan pendekatan lokasi eksternal.

1. Tulis manifes paket

Buat AppxManifest.xml yang menetapkan <uap10:AllowExternalContent>, mendeklarasikan identitas dan kapabilitas, serta mendaftarkan target berbagi. Pastikan Publisher, PackageName, dan ApplicationId tetap sinkron dengan .exe.manifest dan sertifikat penandatanganan Anda.

<Identity Name="PhotoStoreDemo" ProcessorArchitecture="neutral" Publisher="CN=YourPubNameHere" Version="1.0.0.0" />
<Properties>
  <uap10:AllowExternalContent>true</uap10:AllowExternalContent>
</Properties>
<Dependencies>
  <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Capabilities>
  <rescap:Capability Name="runFullTrust" />
  <rescap:Capability Name="unvirtualizedResources" />
</Capabilities>
<Applications>
  <Application Id="PhotoStoreDemo" Executable="PhotoStoreDemo.exe" uap10:TrustLevel="mediumIL" uap10:RuntimeBehavior="win32App">
    <Extensions>
      <uap:Extension Category="windows.shareTarget">
        <uap:ShareTarget Description="Send to PhotoStoreDemo">
          <uap:SupportedFileTypes>
            <uap:FileType>.jpg</uap:FileType>
            <uap:FileType>.png</uap:FileType>
          </uap:SupportedFileTypes>
          <uap:DataFormat>StorageItems</uap:DataFormat>
          <uap:DataFormat>Bitmap</uap:DataFormat>
        </uap:ShareTarget>
      </uap:Extension>
    </Extensions>
  </Application>
</Applications>

Tambahkan manifes aplikasi (YourApp.exe.manifest) yang menautkan executable ke identitas paket:

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="1.0.0.0" name="PhotoStoreDemo.app" />
  <msix xmlns="urn:schemas-microsoft-com:msix.v1"
        publisher="CN=YourPubNameHere"
        packageName="PhotoStoreDemo"
        applicationId="PhotoStoreDemo" />
</assembly>

2. Buat dan tanda tangani paket

Gunakan MakeAppx.exe dengan sakelar /nv untuk membangun paket yang hanya berisi manifes, lalu tanda tangani dengan sertifikat tepercaya menggunakan SignTool.exe:

MakeAppx.exe pack /d <folder with AppxManifest.xml> /p <output>\mypackage.msix /nv
SignTool.exe sign /fd SHA256 /a /f <path to cert> /p <cert key> <path to package>

Instal sertifikat penandatanganan ke lokasi tepercaya pada komputer.

3. Daftarkan paket saat pertama kali dijalankan

Saat pertama kali dijalankan, daftarkan paket lokasi eksternal sehingga aplikasi dimulai ulang dengan identitas. Berikan jalur absolut ke lokasi eksternal dan yang ditandatangani .msix.

[STAThread]
public static void Main(string[] cmdArgs)
{
    if (!ExecutionMode.IsRunningWithIdentity())
    {
        string externalLocation = Environment.CurrentDirectory;
        string externalPkgPath = externalLocation + @"\PhotoStoreDemo.package.msix";

        if (registerPackageWithExternalLocation(externalLocation, externalPkgPath))
        {
            // Registration succeeded - restart so the app runs with identity.
            // Join the arguments into a single string; cmdArgs.ToString() would
            // return the array type name ("System.String[]"), not the arguments.
            string forwardedArgs = cmdArgs is null ? string.Empty : string.Join(" ", cmdArgs);
            Process.Start(Application.ResourceAssembly.Location, arguments: forwardedArgs);
        }
        else
        {
            // Registration failed - run without identity.
            new SingleInstanceManager().Run(cmdArgs);
        }
    }
}

4. Menangani aktivasi berbagi

Setelah aplikasi dimulai ulang dengan identitas, tangani ExtendedActivationKind.ShareTarget seperti yang dijelaskan dalam Menangani aktivasi berbagi.

Untuk contoh lengkapnya, lihat sampel PhotoStoreDemo (dipaketkan dengan lokasi eksternal) dan sampel Target Berbagi WinUI.

Untuk berbagi desktop sisi sumber, gunakan IDataTransferManagerInterop seperti yang dijelaskan dalam Berbagi konten dari aplikasi Anda.

Praktik terbaik

Gunakan daftar periksa ini saat membangun alur penerimaan.

Recommended Hindari Mengapa penting
Deklarasikan hanya ekstensi file dan format data tertentu Menyatakan <uap:SupportsAnyFileType /> untuk aplikasi non-pemindah file Mencegah kemunculan target yang tidak relevan di Lembar Berbagi
Memvalidasi format, jumlah, jenis file, dan ukuran file sebelum diproses Dengan asumsi data masuk selalu sesuai dengan ekspektasi Mencegah kegagalan runtime dan pengalaman berbagi yang rusak
Deklarasikan Uri untuk penangan tautan dan Bitmap + StorageItems untuk penangan gambar Deklarasi parsial untuk payload pembagian umum Memastikan aplikasi Anda muncul untuk konten yang benar-benar didukungnya
Gunakan ReportStarted, ReportDataRetrieved, dan ReportCompleted dalam alur penerimaan yang berjalan lama Melakukan pekerjaan penerimaan jangka panjang tanpa pelaporan kemajuan Menjaga operasi berbagi tetap andal dan memberikan status sistem yang benar

Untuk payload besar atau pemrosesan yang memerlukan waktu lebih lama, laporkan status dari target bagikan:

protected override async void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
{
  ShareOperation shareOperation = args.ShareOperation;
  shareOperation.ReportStarted();

  try
  {
    // Acquire the data your app needs.
    var items = await shareOperation.Data.GetStorageItemsAsync();
    shareOperation.ReportDataRetrieved();

    // Process data.
    await ProcessAsync(items);

    shareOperation.ReportCompleted();
  }
  catch (Exception ex)
  {
    shareOperation.ReportError($"Share failed: {ex.Message}");
  }
}

Gunakan ReportCompleted(QuickLink) saat Anda ingin mengembalikan QuickLink untuk berbagi di masa mendatang.

Troubleshooting

Aplikasi saya tidak muncul di Lembar Berbagi:

  • Verifikasi deklarasi manifes Anda cocok dengan konten yang dibagikan (periksa jenis file dan format data).
  • Untuk aplikasi paket, pastikan Anda menjalankan aplikasi dengan identitas paket.
  • Periksa referensi DataFormat & FileType untuk kategori aplikasi Anda.

Aplikasi saya muncul untuk konten yang tidak dapat ditanganinya:

  • Persempit daftar SupportedFileTypes dan DataFormat Anda hanya ke yang Anda dukung.

Lembar Berbagi ditutup dengan kesalahan:

  • Pastikan Anda memanggil ReportStarted() sebelum memulai operasi async dan ReportCompleted() setelah selesai.
  • Menangani pengecualian dan memanggil ReportError() dengan pesan deskriptif.

Saya tidak menerima file yang saya harapkan:

  • Periksa apakah format file cocok dengan yang dideklarasikan FileType atau DataFormat.
  • Tambahkan logika validasi ke dalam handler aktivasi Anda untuk memeriksa apa yang sebenarnya masuk.