Compartir a través de


Introducción a Las acciones de aplicación en Windows

En este artículo se describen los pasos para crear acciones de aplicación y se describen los componentes de una aplicación de proveedor de acciones de aplicación. Las acciones de aplicación son unidades de comportamiento individuales que una aplicación de Windows puede implementar y registrar para que se pueda acceder a ellas desde otras aplicaciones y experiencias, integrando sin problemas en los flujos de trabajo de usuario. Para obtener más información sobre las acciones de aplicación en Windows, consulte Acciones de aplicación en Información general de Windows.

Las acciones admiten dos modelos de activación diferentes para proveedores de acciones de aplicaciones: activación COM y activación mediante URI. En este artículo se describen los pasos para crear un proveedor de acciones de aplicación que usa la activación COM.

  1. Ejecute uno de los comandos siguientes en Terminal (ya sea un desarrollador de C# o C++). Esto ejecuta un archivo de configuración de WinGet que realiza las siguientes tareas (las dependencias ya instaladas se omitirán):

    • Habilita el modo de desarrollador.
    • Instala Visual Studio Community Edition
    • Incluir carga de trabajo de desarrollo de aplicaciones de Windows y cargas de trabajo de C++ o .NET/C#
    • Incluir herramientas de empaquetado MSIX

Para desarrolladores de C#:

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

Para desarrolladores de C++:

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

Creación de un proyecto de aplicación de Windows en Visual Studio

La característica Acciones de aplicación en Windows es compatible con varios marcos de aplicaciones, pero las aplicaciones deben tener identidad de paquete para poder registrarse en el sistema. En este tutorial se implementará un proveedor de acciones de aplicación de Windows en una aplicación de escritorio de C# WinUI 3 empaquetada.

  1. En Visual Studio, cree un nuevo proyecto.

  2. En el cuadro de diálogo Crear un nuevo proyecto , establezca el filtro de lenguaje en "C#" y el filtro de plataforma en "WinUI", seleccione la plantilla de proyecto "Aplicación vacía, empaquetada (WinUI 3 en escritorio)".

  3. Asigne al nuevo proyecto el nombre "ExampleAppActionProvider".

  4. Cuando se cargue el proyecto, en Explorador de soluciones haga clic con el botón derecho en el nombre del proyecto y seleccione Propiedades. En la página general de , desplácese hacia abajo hasta del sistema operativo de destino y seleccione "Windows". En Versión del sistema operativo de destino y Versión del sistema operativo compatible, seleccione la versión 10.0.26100.0 o posterior.

  5. Para actualizar el proyecto para admitir las API del proveedor de acciones, en el Explorador de soluciones , haga clic con el botón derecho en el nombre del proyecto y seleccione Editar archivo de proyecto. Dentro de PropertyGroup, agregue el siguiente elemento WindowsSdkPackageVersion .

    <WindowsSdkPackageVersion>10.0.26100.59-preview</WindowsSdkPackageVersion>
    

Adición de un archivo JSON de definición de acción

Las aplicaciones del proveedor de acciones deben proporcionar un archivo de definición de acción que defina las acciones que implementa la aplicación. Este archivo proporciona información sobre las entradas y salidas de las acciones y metadatos, como un identificador único y una descripción de las acciones. Para obtener más información sobre el formato de archivo JSON de acción de la aplicación, consulte Esquema JSON de definición de acción para proveedores de acciones de aplicación de Windows.

En este ejemplo se definirá una acción denominada SendMessage, que toma una sola entidad Text como entrada y devuelve una única TextEntity como salida. Además de definir acciones, el archivo JSON también especifica si la aplicación del proveedor de acciones debe iniciarse mediante la activación COM o mediante el inicio del URI. En este ejemplo se usará la activación COM.

  1. En el Explorador de soluciones, haga clic con el botón derecho en el archivo de proyecto ExampleAppActionProvider y seleccione Agregar nuevo> elemento....
  2. En el cuadro de diálogo Agregar nuevo elemento , seleccione Archivo de texto. Asigne al nuevo archivo el nombre "registration.json" y haga clic en Aceptar.
  3. Agregue la siguiente definición de acción JSON al archivo registration.json.
  4. En el Explorador de soluciones, haga clic con el botón derecho en el archivo registration.json y seleccione Propiedades. En el panel Propiedades , establezca Acción de compilación en "Contenido" y establezca Copiar en directorio de salida en "Copiar si es más reciente".
  5. Reemplace el valor invocation.clsid por un nuevo GUID que identificará el proveedor. Para generar un nuevo GUID en Visual Studio, vaya a Herramientas-Crear> GUID. Este GUID se usará de nuevo en algunos lugares diferentes de este tutorial.
{
  "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"
      }
    }
  ]
}

Adición de una clase ActionProvider para controlar las operaciones de acción

Los proveedores de acciones deben implementar la interfaz IActionProvider . Esta interfaz requiere la implementación de un único método , InvokeAsync, que el sistema usa para invocar una acción.

  1. En Visual Studio, haga clic con el botón derecho en el proyecto de AppActionProvider en Explorador de soluciones y seleccione Agregar>Clase.
  2. En el cuadro de diálogo Agregar clase , asigne un nombre a la clase "ActionProvider" y haga clic en Agregar.
  3. En el archivo ActionProvider.cs generado, actualice la definición de clase para indicar que implementa la interfaz IActionProvider .
  4. Etiquete la clase con System.Runtime.InteropServices.GuidAttribute. Esto lo usa el código de activación COM que se muestra más adelante en este tutorial. Asegúrese de actualizar el valor al valor especificado en el campo invocation.clsid del archivo registration.json.
// AppActionProvider.cs
[System.Runtime.InteropServices.GuidAttribute("00001111-aaaa-2222-bbbb-3333cccc4444")] 
public partial class AppActionProvider : IActionProvider

Implementar IActionProvider.InvokeAsync

El método InvokeAsync tiene un tipo de valor devuelto de IAsyncAction. En este ejemplo se usa una clase auxiliar que devuelve un objeto Task, que luego se convierte en IAsyncAction con una llamada al método de extensión AsAsyncAction . Agregue la siguiente definición de método a la clase AppActionProvider .

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

En el método auxiliar InvokeAsyncHelper, se realizan las siguientes acciones:

  • Se llama a ActionInvocationContext.GetInputEntities para recuperar el conjunto de entidades que se pasan como entrada en la acción.
  • Un proveedor de acciones puede admitir varias acciones, por lo que antes de procesar los valores de entrada, se evalúa la propiedad ActionInvocationContext.ActionId para determinar qué acción se invoca. El identificador será el valor declarado para la acción en el campo id del archivo reisgration.json.
  • En este ejemplo, hay una sola entidad de entrada de tipo TextActionEntity denominada "message". El método auxiliar recorre en bucle las entradas y comprueba el nombre esperado.
  • Cuando se encuentra el nombre de entidad de entrada esperado, se convierte al tipo TextEntity y el texto del mensaje se recupera mediante la propiedad Text . En este momento, una implementación real de una acción tomaría este mensaje de entrada, realizaría algún procesamiento en él y generaría una respuesta.
  • En este ejemplo se crea una respuesta TextEntity, tal como se especifica en el campo outputs del archivo registration.json. La entidad se crea a partir de una cadena codificada de forma rígida y, a continuación, se agrega como salida llamando a SetOutputEntity, pasando el nombre de la entidad de salida y el objeto TextEntity .

Agregue la siguiente definición de método a la clase 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;

  }

}

Actualización del archivo de manifiesto del paquete de aplicación

El archivo Package.appmanifest proporciona los detalles del paquete MSIX para una aplicación. Para que el sistema lo registre como proveedor de acciones de la aplicación de Windows, la aplicación debe incluir un elemento uap3:Extension con la categoría establecida en "windows.appExtension". Este elemento se usa para especificar la ubicación del archivo JSON de acción de la aplicación que define las acciones de la aplicación. Para obtener más información sobre el formato del manifiesto del paquete de la aplicación del proveedor de acciones de Windows, consulte el formato XML del manifiesto del paquete del proveedor de aplicaciones de Windows.

En el ejemplo de este tutorial se usa la activación COM para iniciar el proveedor de acciones de la aplicación. Para habilitar la activación COM, use el elemento com2:Extension en el manifiesto del paquete de la aplicación. El valor invocation.clsid especificado en el archivo JSON de definición de acción debe coincidir con el identificador de clase especificado en el elemento com:Class del manifiesto del paquete de la aplicación.

  1. Haga clic con el botón derecho en el archivo Package.appxmanifest y seleccione Ver código.
  2. Agregue los siguientes espacios de nombres al elemento Package en la raíz del archivo.
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. Agregue el siguiente elemento Extensions dentro del elemento Application y después del elemento 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>

Implementación de un generador de clases que creará una instancia de IActionProvider a petición

Una vez que el sistema inicia la aplicación de proveedor de acciones, la aplicación debe llamar a CoRegisterClassObject para que el sistema pueda crear instancias del servidor COM para la implementación de IActionProvider . Esta función requiere una implementación de IClassFactory. En este ejemplo se implementa el generador de clases en una clase auxiliar independiente.

En Visual Studio, haga clic con el botón derecho en el proyecto de ExampleAppActionProvider en Explorador de soluciones y seleccione Agregar>Clase. En el cuadro de diálogo Agregar clase, asigne el nombre "FactoryHelper" a la clase y haga clic en Agregar.

Reemplace el contenido del archivo FactoryHelper.cs por el código siguiente. Este código define la interfaz IClassFactory e implementa sus dos métodos, CreateInstance y LockServer. Este código es típico estándar para implementar un generador de clases y no es específico de la funcionalidad de un proveedor de acciones de aplicación, excepto que indica que el objeto de la clase que se crea implementa la interfaz 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;

    }
}

Implementación de un método Main personalizado

En la plantilla de proyecto predeterminada, el compilador genera automáticamente el punto de entrada del método Main . En este ejemplo se deshabilitará la autogeneración de Main para que se pueda ejecutar el código de activación necesario en el inicio.

  1. En el Explorador de soluciones, haga clic con el botón derecho en el icono del proyecto y seleccione Editar archivo de proyecto.
  2. En el elemento PropertyGroup , agregue el siguiente elemento secundario para deshabilitar la función principal generada automáticamente.
<DefineConstants>$(DefineConstants);DISABLE_XAML_GENERATED_MAIN</DefineConstants>

A continuación, en el Explorador de soluciones, haga clic con el botón derecho en el icono del proyecto y seleccione Agregar clase>. Cambie el nombre de archivo a "Program.cs" y haga clic en Agregar.

En el archivo Program.cs del archivo ejecutable, se llama a CoRegisterClassObject para registrar el servidor COM del proveedor de acciones. Reemplace el contenido de Program.cs por el código siguiente. Este código importa la función CoRegisterClassObject y la llama, pasando la clase ActionProviderFactory definida en un paso anterior. Asegúrese de actualizar la declaración de variable CLSID_Factory para usar el GUID que especificó en el archivo 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;

Probar la acción de la aplicación de Windows

La aplicación App Actions Testing Playground te permite validar el registro y la funcionalidad de la aplicación del proveedor de acciones de aplicaciones de Windows. Para obtener más información sobre el uso de esta herramienta, consulte App Actions Testing Playground.