Bagikan melalui


Mulai menggunakan Tindakan Aplikasi di Windows

Artikel ini menjelaskan langkah-langkah untuk membuat tindakan aplikasi dan menjelaskan komponen aplikasi penyedia App Action. Tindakan aplikasi adalah unit perilaku individual yang dapat diterapkan dan didaftarkan aplikasi Windows sehingga dapat diakses dari aplikasi dan pengalaman lain, terintegrasi dengan mulus ke dalam alur kerja pengguna. Untuk informasi selengkapnya tentang Tindakan Aplikasi di Windows, lihat Tindakan Aplikasi di Gambaran Umum Windows

Aksi mendukung dua model aktivasi yang berbeda untuk penyedia aksi aplikasi, aktivasi COM dan aktivasi peluncuran URI. Artikel ini menjelaskan langkah-langkah pembuatan penyedia tindakan aplikasi yang menggunakan aktivasi COM.

  1. Jalankan salah satu perintah di bawah ini di Terminal (baik Anda pengembang C# atau C++). Ini menjalankan file Konfigurasi WinGet yang melakukan tugas berikut (dependensi yang sudah diinstal akan dilewati):

    • Mengaktifkan Mode Pengembang.
    • Menginstal Visual Studio Community Edition
    • Sertakan beban kerja pengembangan Aplikasi Windows dan Beban Kerja C++ atau .NET/C#
    • Menyertakan alat Kemasan MSIX

Untuk pengembang C#:

winget configure https://raw.githubusercontent.com/microsoft/winget-dsc/refs/heads/main/samples/Configuration%20files/Learn%20tutorials/Windows%20AI/app_actions_cs.winget

Untuk pengembang C++:

winget configure https://raw.githubusercontent.com/microsoft/winget-dsc/refs/heads/main/samples/Configuration%20files/Learn%20tutorials/Windows%20AI/app_actions_cpp.winget

Membuat proyek aplikasi Windows baru di Visual Studio

Fitur App Actions di Windows didukung untuk beberapa kerangka kerja aplikasi, tetapi aplikasi harus memiliki identitas paket untuk dapat mendaftar dengan sistem. Panduan ini akan mengimplementasikan penyedia tindakan aplikasi Windows dalam aplikasi desktop C# WinUI 3 yang dipaketkan.

  1. Di Visual Studio, buat proyek baru.

  2. Dalam dialog Buat proyek baru , atur filter bahasa ke "C#" dan filter platform ke "WinUI", lalu pilih templat proyek "Aplikasi Kosong, Dipaketkan (WinUI 3 di Desktop)".

  3. Beri nama proyek baru "ExampleAppActionProvider".

  4. Saat proyek dimuat, di Penjelajah Solusi klik kanan nama proyek dan pilih Properti. Pada halaman Umum, gulir ke OS Target dan pilih "Windows". Untuk Versi OS target dan versi OS yang didukung, pilih versi 10.0.26100.0 atau yang lebih tinggi.

  5. Untuk memperbarui proyek Anda guna mendukung API Penyedia Tindakan, di Penjelajah Solusi klik kanan nama proyek dan pilih Edit File Proyek. Di dalam PropertyGroup, tambahkan elemen WindowsSdkPackageVersion berikut.

    <WindowsSdkPackageVersion>10.0.26100.59-preview</WindowsSdkPackageVersion>
    

Menambahkan definisi tindakan file JSON

Aplikasi penyedia tindakan harus menyediakan file definisi tindakan yang menentukan tindakan yang diterapkan aplikasi. File ini menyediakan informasi tentang input dan output tindakan dan metadata Anda seperti pengidentifikasi unik dan deskripsi untuk tindakan Anda. Untuk informasi selengkapnya tentang format file JSON Tindakan Aplikasi, lihat Skema JSON definisi tindakan untuk penyedia Tindakan Aplikasi Windows.

Contoh ini akan menentukan satu tindakan yang disebut SendMessage, yang mengambil satu entitas Teks sebagai input, dan mengembalikan satu TextEntity sebagai output. Selain menentukan tindakan, file JSON juga menentukan apakah aplikasi penyedia tindakan harus diluncurkan menggunakan aktivasi COM atau melalui peluncuran URI. Contoh ini akan menggunakan aktivasi COM.

  1. Di Penjelajah Solusi, klik kanan file proyek ExampleAppActionProvider dan pilih Tambahkan> Item Baru....
  2. Dalam dialog Tambahkan Item Baru , pilih File Teks. Beri nama file baru "registration.json", dan klik OK.
  3. Tambahkan definisi tindakan JSON berikut ke file registration.json.
  4. Di Penjelajah Solusi, klik kanan file registration.json dan pilih Properti. Di panel Properti, atur Aksi Build ke "Konten" dan atur Salin ke Direktori Output ke "Salin jika Lebih Baru".
  5. Ganti nilai invocation.clsid dengan GUID baru yang akan mengidentifikasi penyedia. Anda dapat membuat GUID baru di Visual Studio dengan membuka ALAT-Buat> GUID. GUID ini akan digunakan lagi di beberapa tempat berbeda dalam panduan ini.
{
  "version": 2,
  "actions": [
    {
      "id": "ExampleAppActionProvider.SendMessage",
      "description": "Send a message",
      "icon": "ms-resource://Files/Assets/StoreLogo.png",
      "usesGenerativeAI": false,
      "inputs": [
        {
          "name": "message",
          "kind": "Text"
        }
      ],
      "inputCombinations": [
        {
          "inputs": [
            "message"
          ],
          "description": "Send message '${message.Text}'"
        }
      ],
      "outputs": [
        {
          "name": "response",
          "kind": "Text"
        }
      ],
      "invocation": {
        "type": "COM",
        "clsid": "00001111-aaaa-2222-bbbb-3333cccc4444"
      }
    }
  ]
}

Menambahkan kelas ActionProvider untuk menangani operasi tindakan

Penyedia tindakan harus menerapkan antarmuka IActionProvider . Antarmuka ini memerlukan implementasi satu metode, InvokeAsync, yang digunakan sistem untuk memanggil tindakan.

  1. Di Visual Studio, klik kanan proyek AppActionProvider di Penjelajah Solusi dan pilih Add->Class.
  2. Dalam dialog Tambahkan kelas , beri nama kelas "ActionProvider" dan klik Tambahkan.
  3. Dalam file ActionProvider.cs yang dihasilkan, perbarui definisi kelas untuk menunjukkan bahwa file tersebut mengimplementasikan antarmuka IActionProvider .
  4. Beri label kelas dengan System.Runtime.InteropServices.GuidAttribute. Ini digunakan oleh kode aktivasi COM yang ditunjukkan nanti dalam panduan ini. Pastikan untuk memperbarui nilai ke nilai yang ditentukan di bidang invocation.clsid dalam file registration.json.
// AppActionProvider.cs
[System.Runtime.InteropServices.GuidAttribute("00001111-aaaa-2222-bbbb-3333cccc4444")] 
public partial class AppActionProvider : IActionProvider

Menerapkan IActionProvider.InvokeAsync

Metode InvokeAsync memiliki jenis pengembalian IAsyncAction. Contoh ini menggunakan kelas pembantu yang mengembalikan Tugas, yang kemudian dikonversi ke IAsyncAction dengan panggilan ke metode ekstensi AsAsyncAction . Tambahkan definisi metode berikut ke kelas AppActionProvider .

// AppActionProvider.cs
public IAsyncAction InvokeAsync(ActionInvocationContext context)
{
    return InvokeAsyncHelper(context).AsAsyncAction();
}

Dalam metode pembantu, InvokeAsyncHelper, tindakan berikut dilakukan:

  • ActionInvocationContext.GetInputEntities dipanggil untuk mengambil kumpulan entitas yang diteruskan sebagai input ke dalam tindakan.
  • Penyedia tindakan dapat mendukung beberapa tindakan, jadi sebelum memproses nilai input, properti ActionInvocationContext.ActionId dievaluasi untuk menentukan tindakan mana yang sedang dipanggil. ID akan menjadi nilai yang dideklarasikan untuk tindakan di bidang id dalam file reisgration.json.
  • Dalam contoh ini, ada entitas input tunggal dari jenis TextActionEntity bernama "message". Metode pembantu mengiterasi input dan memeriksa nama yang sesuai harapan.
  • Ketika nama entitas input yang diharapkan ditemukan, itu ditransmisikan ke jenis TextEntity , dan teks pesan diambil menggunakan properti Teks . Pada titik ini, implementasi tindakan dunia nyata akan mengambil pesan input ini, melakukan beberapa pemrosesan di atasnya, dan menghasilkan respons.
  • Contoh ini membuat respons TextEntity, seperti yang ditentukan di bidang outputs dalam file registration.json. Entitas dibuat dari string yang dikodekan secara permanen lalu ditambahkan sebagai output dengan memanggil ke SetOutputEntity, meneruskan nama entitas output dan objek TextEntity .

Tambahkan definisi metode berikut ke kelas AppActionProvider .

// AppActionProvider.cs
async Task InvokeAsyncHelper(ActionInvocationContext context)
{
    NamedActionEntity[] inputs = context.GetInputEntities();

    var actionId = context.ActionId;
    switch (actionId)
    {
      case "ExampleActionProvider.SendMessage":
          foreach (NamedActionEntity inputEntity in inputs)
          {
              if (inputEntity.Name.Equals("message", StringComparison.Ordinal))
              {
                
                TextActionEntity entity = (TextActionEntity)(inputEntity.Entity);
                string message = entity.Text;
                
                // TODO: Process the message and generate a response

                string response = "This is the message response"; 
                TextActionEntity result = context.EntityFactory.CreateTextEntity(response);
                context.SetOutputEntity("response", result);

              }

          }

          break;

      default:

          break;

  }

}

Memperbarui file manifes paket aplikasi

File Package.appmanifest menyediakan detail paket MSIX untuk aplikasi. Untuk didaftarkan oleh sistem sebagai penyedia Tindakan Aplikasi Windows, aplikasi harus menyertakan elemen uap3:Extension dengan Kategori yang diatur ke "windows.appExtension". Elemen ini digunakan untuk menentukan lokasi file JSON Tindakan Aplikasi yang menentukan tindakan aplikasi. Untuk informasi selengkapnya tentang format manifes paket aplikasi penyedia tindakan, lihat Format XML manifes paket penyedia Tindakan Aplikasi Windows.

Contoh dalam panduan ini menggunakan aktivasi COM untuk meluncurkan penyedia tindakan aplikasi. Untuk mengaktifkan aktivasi COM, gunakan elemen com2:Extension dalam manifes paket aplikasi. Nilai invocation.clsid yang ditentukan dalam file JSON Definisi tindakan harus cocok dengan ID kelas yang ditentukan dalam elemen com:Class dalam manifes paket aplikasi.

  1. Klik kanan file Package.appxmanifest dan pilih Tampilkan Kode
  2. Tambahkan namespace berikut ke elemen Paket di akar file.
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
xmlns:com2="http://schemas.microsoft.com/appx/manifest/com/windows10/2"
xmlns:com3="http://schemas.microsoft.com/appx/manifest/com/windows10/3"
  1. Tambahkan elemen Ekstensi berikut di dalam elemen Aplikasi dan setelah elemen VisualElements .
<Extensions>
  <com2:Extension Category="windows.comServer">
    <com2:ComServer>
        <com3:ExeServer Executable="ExampleAppActionProvider.exe" DisplayName="ExampleAppActionProvider">
            <com:Class Id="00001111-aaaa-2222-bbbb-3333cccc4444" DisplayName="ExampleAppActionProvider" />
        </com3:ExeServer>
      </com2:ComServer>
    </com2:Extension>
    <uap3:Extension Category="windows.appExtension">
        <uap3:AppExtension Name="com.microsoft.windows.ai.actions" DisplayName="Example App Action Provider" Id="appactionprovider" PublicFolder="Assets">
        <uap3:Properties>
            <Registration xmlns="">registration.json</Registration>
        </uap3:Properties>
    </uap3:AppExtension>
</uap3:Extension>
</Extensions>

Menerapkan fabrikasi kelas yang akan menginstansiasi IActionProvider ketika diminta

Setelah sistem meluncurkan aplikasi penyedia tindakan, aplikasi harus memanggil CoRegisterClassObject sehingga sistem dapat membuat instans server COM untuk implementasi IActionProvider . Fungsi ini memerlukan implementasi IClassFactory. Contoh ini mengimplementasikan pabrik kelas di kelas pembantu terpadu.

Di Visual Studio, klik kanan proyek ExampleAppActionProvider di Penjelajah Solusi dan pilih Add->Class. Dalam dialog Tambahkan kelas, beri nama kelas "FactoryHelper" dan klik Tambahkan.

Ganti konten file FactoryHelper.cs dengan kode berikut. Kode ini mendefinisikan antarmuka IClassFactory dan mengimplementasikan dua metodenya, CreateInstance dan LockServer. Kode ini adalah boilerplate khas untuk menerapkan pabrik kelas dan tidak spesifik untuk fungsionalitas penyedia tindakan aplikasi kecuali menunjukkan bahwa objek kelas yang dibuat mengimplementasikan antarmuka IActionProvider .

// FactoryHelper.cs

using Microsoft.Windows.Widgets.Providers;
using System.Runtime.InteropServices;
using WinRT;

namespace COM
{
    static class Guids
    {
        public const string IClassFactory = "00000001-0000-0000-C000-000000000046";
        public const string IUnknown = "00000000-0000-0000-C000-000000000046";
    }

    /// 
    /// IClassFactory declaration
    /// 
    [ComImport, ComVisible(false), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid(COM.Guids.IClassFactory)]
    internal interface IClassFactory
    {
        [PreserveSig]
        int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject);
        [PreserveSig]
        int LockServer(bool fLock);
    }

    [ComVisible(true)]
    class WidgetProviderFactory<T> : IClassFactory
    where T : IActionProvider, new()
    {
        public int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject)
        {
            ppvObject = IntPtr.Zero;

            if (pUnkOuter != IntPtr.Zero)
            {
                Marshal.ThrowExceptionForHR(CLASS_E_NOAGGREGATION);
            }

            if (riid == typeof(T).GUID || riid == Guid.Parse(COM.Guids.IUnknown))
            {
                // Create the instance of the .NET object
                ppvObject = MarshalInspectable<IActionProvider>.FromManaged(new T());
            }
            else
            {
                // The object that ppvObject points to does not support the
                // interface identified by riid.
                Marshal.ThrowExceptionForHR(E_NOINTERFACE);
            }

            return 0;
        }

        int IClassFactory.LockServer(bool fLock)
        {
            return 0;
        }

        private const int CLASS_E_NOAGGREGATION = -2147221232;
        private const int E_NOINTERFACE = -2147467262;

    }
}

Menerapkan metode Utama kustom

Dalam templat proyek default, titik entri metode Utama dibuat secara otomatis oleh pengompilasi. Contoh ini akan menonaktifkan pembuatan otomatis Main sehingga kode aktivasi yang diperlukan dapat dijalankan saat startup.

  1. Di Penjelajah Solusi, klik kanan ikon proyek dan pilih Edit File Proyek.
  2. Dalam elemen PropertyGroup , tambahkan elemen turunan berikut untuk menonaktifkan fungsi utama yang dihasilkan secara otomatis.
<DefineConstants>$(DefineConstants);DISABLE_XAML_GENERATED_MAIN</DefineConstants>

Selanjutnya, di Penjelajah Solusi, klik kanan ikon proyek dan pilih Add-Class>. Ubah nama file menjadi "Program.cs" dan klik Tambahkan.

Dalam berkas Program.cs untuk aplikasi yang dapat dieksekusi, CoRegisterClassObject dipanggil untuk mendaftarkan server COM penyedia aksi. Ganti konten Program.cs dengan kode berikut. Kode ini mengimpor fungsi CoRegisterClassObject dan memanggilnya, melewati kelas ActionProviderFactory yang ditentukan pada langkah sebelumnya. Pastikan untuk memperbarui deklarasi variabel CLSID_Factory untuk menggunakan GUID yang Anda tentukan dalam file registration.json.

// Program.cs

using System.Runtime.InteropServices;
using ComTypes = System.Runtime.InteropServices.ComTypes;
using Microsoft.Windows.Widgets;
using ExampleWidgetProvider;
using COM;
using System;


[DllImport("ole32.dll")]

static extern int CoRegisterClassObject(
            [MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
            [MarshalAs(UnmanagedType.IUnknown)] object pUnk,
            uint dwClsContext,
            uint flags,
            out uint lpdwRegister);

[DllImport("ole32.dll")] static extern int CoRevokeClassObject(uint dwRegister);

uint cookie;

Guid CLSID_Factory = Guid.Parse("00001111-aaaa-2222-bbbb-3333cccc4444");
CoRegisterClassObject(CLSID_Factory, new ActionProviderFactory<AppActionProvider>(), 0x4, 0x1, out cookie);

Application.Start((p) =>
{
    var context = new DispatcherQueueSynchronizationContext(
        DispatcherQueue.GetForCurrentThread());
    SynchronizationContext.SetSynchronizationContext(context);
    _ = new App();
});

PInvoke.CoRevokeClassObject(cookie);

return 0;

Menguji Tindakan Aplikasi Windows

Aplikasi App Actions Testing Playground memungkinkan Anda memvalidasi pendaftaran dan fungsionalitas aplikasi penyedia Windows App Action Anda. Untuk informasi selengkapnya tentang menggunakan alat ini, lihat App Actions Testing Playground.