Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este inicio rápido, creará una aplicación de Windows de escritorio que envía y recibe notificaciones push mediante el SDK de Aplicaciones para Windows.
Prerequisites
- Start developing Windows apps
- Crear un nuevo proyecto que use el SDK de Aplicaciones para Windows OR Use el SDK de Aplicaciones para Windows en un proyecto existente
- Se requiere un Azure Account para poder usar SDK de Aplicaciones para Windows notificaciones push.
- Lea la visión general de las notificaciones push
Requisitos de empaquetado
Las notificaciones push en la SDK de Aplicaciones para Windows admiten aplicaciones de escritorio empaquetadas y realmente desempaquetadas. Sin embargo, el escenario de producción más común requiere la identidad del paquete para la entrega en segundo plano y la activación COM. En la tabla siguiente se resumen los requisitos en función del modelo de empaquetado:
| Modelo de empaquetado | Se requiere el activador COM | Se requiere la asignación de PFN | Se admite sin empaquetar |
|---|---|---|---|
| Paquete MSIX (WinUI 3, paquete WPF/WinForms) | Sí, en Package.appxmanifest |
Sí, a través del correo electrónico de mapeo PFN | No |
| Empaquetado con ubicación externa | Sí, en Package.appxmanifest |
Sí, a través del correo electrónico de asignación de PFN | No |
| Verdaderamente desempaquetado (sin identidad de paquete) | No (omitir paso 3) | No | Sí: funcionalidad limitada |
Important
Si la aplicación está empaquetada (MSIX o empaquetada con ubicación externa), debes asignar el nombre de familia del paquete (PFN) de la aplicación a su Azure AppId antes de que funcionen las notificaciones push. Las solicitudes de asignación se envían por correo electrónico a Win_App_SDK_Push@microsoft.com y se procesan de forma semanal. Planee este plazo antes de su lanzamiento.
Consulte Paso 4: Vincule el nombre de familia de paquete de la aplicación a su ID de la aplicación en Azure para más detalles.
Aplicación de ejemplo
En este inicio rápido se explica cómo agregar compatibilidad con notificaciones push a la aplicación en SDK de Aplicaciones para Windows 1.7. Consulte código similar a este inicio rápido en las aplicaciones de ejemplo que se encuentran en GitHub. Asegúrese de consultar el branch con su versión preferida de la SDK de Aplicaciones para Windows para ver los ejemplos que mejor coincidan con el proyecto.
También puede encontrar ejemplos para cada versión de SDK de Aplicaciones para Windows seleccionando una rama de versión en el repositorio de ejemplos.
Referencia de API
Para obtener documentación de referencia de API para las notificaciones push, consulte Microsoft.Windows. PushNotifications Namespace.
Configuración de la identidad de la aplicación en Azure Active Directory (AAD)
Las notificaciones push en SDK de Aplicaciones para Windows usan identidades de Azure Active Directory (AAD). Azure credenciales son necesarias al solicitar un URI del canal WNS y al solicitar tokens de acceso para enviar notificaciones push. Nota: NO admitimos el uso de notificaciones push de SDK de Aplicaciones para Windows en el Microsoft Partner Center.
Paso 1: Creación de un registro de aplicaciones de AAD
Inicie sesión en la cuenta de Azure y cree un nuevo recurso AAD App Registration. Seleccione Nuevo registro.
Paso 2: Proporcionar un nombre y seleccionar una opción multiinquilino
Especifique un nombre de la aplicación.
Las notificaciones push requieren la opción multiinquilino, así que selecciónela.
- Para obtener más información sobre los inquilinos, consulte ¿Quién puede iniciar sesión en la aplicación?
Seleccione Registrar.
Tome nota del ID de aplicación (cliente), ya que este es su Azure AppId que usará durante el registro de activación y la solicitud de token de acceso.
Tome nota de su ID de Directorio (tenant), ya que esta es su Identificador de inquilino de Azure que utilizará para solicitar un token de acceso.
Important
Tome nota de la id. de aplicación (cliente) y id. de directorio (inquilino).Tome nota de su ID de objeto, ya que este es su ID de objeto de Azure que usará al hacer una solicitud de canal. Tenga en cuenta que no es el identificador de objeto que aparece en la página Essentials . En su lugar, para encontrar el identificador de objeto correcto
, haga clic en el nombre de la aplicación en el campo de la aplicación administrada en el directorio local en la página de Essentials .
Captura de pantalla de

Note
Se requiere un principal de servicio para obtener un identificador de objeto, si no hay ninguno asociado a la aplicación, siga los pasos de uno de los siguientes artículos para crear uno en el portal de Azure o mediante la línea de comandos:
Utilice Azure PowerShell para crear una entidad de servicio con un certificado
Paso 3: Crear un secreto para el registro de la aplicación
El secreto se usará junto con el Azure AppId/ClientId al solicitar un token de acceso para enviar notificaciones push.
Secreto de la aplicación AAD
Vaya a Certificados y secretos y seleccione Nuevo secretos de cliente.
Important
Asegúrese de copiar el secreto una vez creado y almacenarlo en una ubicación segura, como Azure Key Vault. Solo se podrá ver una vez después de la creación.
Paso 4: Relacionar el Package Family Name de la aplicación con su Azure AppId
Si la aplicación está empaquetada (incluida la empaquetada con una ubicación externa), puedes usar este flujo para asignar el nombre de familia de paquetes (PFN) de la aplicación y su Azure AppId.
Si la aplicación es una aplicación Win32 empaquetada, cree una solicitud de asignación de nombre de familia de paquetes (PFN) enviando un correo electrónico a Win_App_SDK_Push@microsoft.com con la línea de asunto "Solicitud de Asignación de Notificaciones Push de SDK de Aplicaciones para Windows" y cuerpo "PFN: [su PFN]", AppId: [su AppId], ObjectId: [su ObjectId]. Las solicitudes de mapeo se completan semanalmente. Recibirá una notificación una vez completada la solicitud de asignación.
Una vez que tenga su Azure AppId, ObjectId y secret, puede agregar esas credenciales al código de ejemplo siguiente.
Configuración de la aplicación para recibir notificaciones push
Paso 1: Agregar SDK de Aplicaciones para Windows y paquetes NuGet necesarios
A continuación, haga clic con el botón derecho en la solución en el Explorador de soluciones y seleccione Administrar paquetes NuGet.
En el Administrador de paquetes, agregue los siguientes paquetes:
- Microsoft. WindowsAppSDK (versión mínima 1.1.0)
- Microsoft. Windows. SDK. BuildTools (versión mínima 10.0.22000.194)
- Microsoft. Windows. CppWinRT, (versión mínima 2.0.210930.14)
- Microsoft. Windows. ImplementationLibrary, (versión mínima 1.0.210930.1)
Si esta es la primera vez que usa SDK de Aplicaciones para Windows en el proyecto y se empaqueta con ubicación externa o sin empaquetar, inicialice el SDK de Aplicaciones para Windows agregando la siguiente propiedad al archivo de proyecto:
<!-- your .vcxproj or .proj file -->
<PropertyGroup Label="Globals">
<!-- Other properties -->
<WindowsPackageType>None</WindowsPackageType>
</PropertyGroup>
o utilizar la API de bootstrapper. Consulte Usar el entorno de ejecución de SDK de Aplicaciones para Windows para aplicaciones empaquetadas con una ubicación externa o sin empaquetar para obtener más información.
Note
Si el SDK no se inicializa, la aplicación generará System.Runtime.InteropServices.COMException (0x80040154): Class not registered (0x80040154 (REGDB_E_CLASSNOTREG)) y no funcionará.
Paso 2: Agregar namespaces
A continuación, agregue el espacio de nombres para las notificaciones push de SDK de Aplicaciones para Windows Microsoft.Windows.PushNotifications.
#include <winrt/Microsoft.Windows.PushNotifications.h>
using namespace winrt::Microsoft::Windows::PushNotifications;
Si recibe un mensaje "Can't find Microsoft.Windows.PushNotifications", eso probablemente significa que no se han generado los archivos de encabezado. Para resolverlo, asegúrese de que tiene instalados los paquetes anteriores, convierta en comentario las instrucciones include y using que provocan el error y recompile la aplicación para generar los archivos de encabezado. Una vez que la compilación se realice correctamente, descomente las instrucciones "include" y "using" y vuelva a compilar el proyecto. Esto debe resolver el error.
Paso 3: Agregar el activador COM al manifiesto de la aplicación
Important
Si la aplicación está desempaquetada (es decir, carece de identidad de paquete en tiempo de ejecución), vaya al paso 4: Registrar y responder a las notificaciones push en el inicio de la aplicación.
Si tu aplicación está empaquetada (incluyendo si está empaquetada con ubicación externa): abre el Package.appxmanifest. Agregue lo siguiente dentro del <Application> elemento . Reemplace los Idvalores , Executabley DisplayName por los específicos de la aplicación.
<!--Packaged apps only-->
<!--package.appxmanifest-->
<Package
...
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
...
<Applications>
<Application>
...
<Extensions>
<!--Register COM activator-->
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer Executable="SampleApp\SampleApp.exe" DisplayName="SampleApp" Arguments="----WindowsAppRuntimePushServer:">
<com:Class Id="[Your app's Azure AppId]" DisplayName="Windows App SDK Push" />
</com:ExeServer>
</com:ComServer>
</com:Extension>
</Extensions>
</Application>
</Applications>
</Package>
Note
El atributo Id en <com:Class> debe establecerse en el ID de aplicación de Azure (el ID de aplicación (cliente) de su registro de aplicaciones de Azure AD). Así es como SDK de Aplicaciones para Windows conecta la activación COM de tu aplicación con su identidad de Azure: cuando WNS activa tu aplicación para entregar una notificación push en segundo plano, utiliza este GUID para localizar e iniciar el servidor COM correcto. Use el mismo valor Azure AppId que anotó en el paso 1 anterior.
Note
Se puede encontrar un ejemplo de la clase de C++ completada para este ejemplo después del paso 5. Los pasos 4 y 5 proporcionan instrucciones paso a paso para agregar cada pieza en el ejemplo final.
Paso 4: Registrar y responder a notificaciones push en el inicio de la aplicación
Actualice el método de su aplicación main() para agregar lo siguiente:
- Registre su aplicación para recibir notificaciones push llamando a PushNotificationManager::Default().Register().
- Compruebe el origen de la solicitud de activación llamando a AppInstance::GetCurrent(). GetActivatedEventArgs(). Si la activación se desencadenó desde una notificación push, responda en función de la carga útil de la notificación.
Important
Debe llamar a PushNotificationManager::D efault(). Registre antes de llamar a AppInstance.GetCurrent.GetActivatedEventArgs.
Adición de controladores de eventos en primer plano
Para controlar un evento en primer plano, registre un controlador para PushNotificationManager.PushReceived.
Important
También debe registrar los controladores de eventos PushNotificationManager.PushReceived antes de llamar a PushNotificationManager.Register(). De lo contrario, se producirá la siguiente excepción en tiempo de ejecución:
System.Runtime.InteropServices.COMException: Element not found. Must register event handlers before calling Register().
Agregue la comprobación PushNotificationManager::IsSupported()
A continuación, agregue una comprobación para ver si las API de notificaciones Push son compatibles con PushNotificationManager.IsSupported(). Si no es así, te recomendamos usar el sondeo o tu propia implementación personalizada de sockets.
Ahora que hay soporte para notificaciones push confirmadas, agrega el comportamiento basado en PushNotificationReceivedEventArgs.
Paso 5: Solicitar un URI del canal WNS y registrarlo con el servidor WNS
Los URI del canal WNS son los puntos de conexión HTTP para enviar notificaciones push. Cada cliente debe solicitar un URI de canal y registrarlo en el servidor WNS para recibir notificaciones push.
Note
Los URI del canal WNS expiran después de 30 días. Solicite un URI de canal nuevo cada vez que se inicie la aplicación, en lugar de almacenar en caché uno anterior. Cuando el nuevo URI difiere de lo que el back-end ha almacenado, envíe el URI actualizado al servicio en la nube para que pueda mantener sus registros actualizados. No supongamos que el URI permanecerá estable entre sesiones: tratarlo como un valor mutable y con ámbito de sesión evita errores de entrega silenciosos causados por URI de canal expirados o obsoletos.
auto channelOperation{ PushNotificationManager::Default().CreateChannelAsync(winrt::guid("[Your app's Azure ObjectID]")) };
Si sigue el código del tutorial, agregue el identificador de objeto de Azure aquí:
// To obtain an AAD RemoteIdentifier for your app,
// follow the instructions on https://dori-uw-1.kuma-moon.com/azure/active-directory/develop/quickstart-register-app
winrt::guid remoteId{ "00000000-0000-0000-0000-000000000000" }; // Replace this with your own Azure ObjectId
El PushNotificationManager intentará crear un URI de canal, reintentando automáticamente durante no más de 15 minutos. Cree un controlador de eventos para esperar a que se complete la llamada. Una vez completada la llamada, si se realizó correctamente, registre el URI con el servidor WNS.
Código de ejemplo
#include <iostream>
#include <winrt/Microsoft.Windows.PushNotifications.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Microsoft.Windows.AppLifecycle.h>
#include <winrt/Windows.ApplicationModel.Background.h>
#include <wil/cppwinrt.h>
#include <wil/result.h>
using namespace winrt::Microsoft::Windows::PushNotifications;
using namespace winrt::Windows::Foundation;
using namespace winrt::Microsoft::Windows::AppLifecycle;
// To obtain an AAD RemoteIdentifier for your app,
// follow the instructions on https://dori-uw-1.kuma-moon.com/azure/active-directory/develop/quickstart-register-app
winrt::guid remoteId{ "00000000-0000-0000-0000-000000000000" }; // Replace this with your own Azure ObjectId
winrt::Windows::Foundation::IAsyncOperation<PushNotificationChannel> RequestChannelAsync()
{
auto channelOperation = PushNotificationManager::Default().CreateChannelAsync(remoteId);
// Set up the in-progress event handler
channelOperation.Progress(
[](auto&& sender, auto&& args)
{
if (args.status == PushNotificationChannelStatus::InProgress)
{
// This is basically a noop since it isn't really an error state
std::cout << "Channel request is in progress." << std::endl << std::endl;
}
else if (args.status == PushNotificationChannelStatus::InProgressRetry)
{
LOG_HR_MSG(
args.extendedError,
"The channel request is in back-off retry mode because of a retryable error! Expect delays in acquiring it. RetryCount = %d",
args.retryCount);
}
});
auto result = co_await channelOperation;
if (result.Status() == PushNotificationChannelStatus::CompletedSuccess)
{
auto channelUri = result.Channel().Uri();
std::cout << "channelUri: " << winrt::to_string(channelUri.ToString()) << std::endl << std::endl;
auto channelExpiry = result.Channel().ExpirationTime();
// Caller's responsibility to keep the channel alive
co_return result.Channel();
}
else if (result.Status() == PushNotificationChannelStatus::CompletedFailure)
{
LOG_HR_MSG(result.ExtendedError(), "We hit a critical non-retryable error with channel request!");
co_return nullptr;
}
else
{
LOG_HR_MSG(result.ExtendedError(), "Some other failure occurred.");
co_return nullptr;
}
};
PushNotificationChannel RequestChannel()
{
auto task = RequestChannelAsync();
if (task.wait_for(std::chrono::seconds(300)) != AsyncStatus::Completed)
{
task.Cancel();
return nullptr;
}
auto result = task.GetResults();
return result;
}
void SubscribeForegroundEventHandler()
{
winrt::event_token token{ PushNotificationManager::Default().PushReceived([](auto const&, PushNotificationReceivedEventArgs const& args)
{
auto payload{ args.Payload() };
std::string payloadString(payload.begin(), payload.end());
std::cout << "\nPush notification content received in the FOREGROUND: " << payloadString << std::endl;
}) };
std::cout << "Push notification foreground event handler registered." << std::endl;
}
int main()
{
// Set up an event handler, so we can receive notifications in the foreground while the app is running.
// You must register notification event handlers before calling Register(). Otherwise, the following runtime
// exception will be thrown: System.Runtime.InteropServices.COMException: 'Element not found. Must register
// event handlers before calling Register().'
SubscribeForegroundEventHandler();
// Register the app for push notifications.
PushNotificationManager::Default().Register();
auto args{ AppInstance::GetCurrent().GetActivatedEventArgs() };
switch (args.Kind())
{
case ExtendedActivationKind::Launch:
{
std::cout << "App launched by user or from the debugger." << std::endl;
if (PushNotificationManager::IsSupported())
{
std::cout << "Push notifications are supported on this device." << std::endl;
// Request a WNS Channel URI which can be passed off to an external app to send notifications to.
// The WNS Channel URI uniquely identifies this app for this user and device.
PushNotificationChannel channel{ RequestChannel() };
if (!channel)
{
std::cout << "\nThere was an error obtaining the WNS Channel URI" << std::endl;
if (remoteId == winrt::guid{ "00000000-0000-0000-0000-000000000000" })
{
std::cout << "\nThe ObjectID has not been set. Refer to the readme file accompanying this sample\nfor the instructions on how to obtain and setup an ObjectID" << std::endl;
}
}
std::cout << "\nPress 'Enter' at any time to exit App." << std::endl;
std::cin.ignore();
}
else
{
std::cout << "Push notifications are NOT supported on this device." << std::endl;
std::cout << "App implements its own custom socket here to receive messages from the cloud since Push APIs are unsupported." << std::endl;
std::cin.ignore();
}
}
break;
case ExtendedActivationKind::Push:
{
std::cout << "App activated via push notification." << std::endl;
PushNotificationReceivedEventArgs pushArgs{ args.Data().as<PushNotificationReceivedEventArgs>() };
// Call GetDeferral to ensure that code runs in low power
auto deferral{ pushArgs.GetDeferral() };
auto payload{ pushArgs.Payload() };
// Do stuff to process the raw notification payload
std::string payloadString(payload.begin(), payload.end());
std::cout << "\nPush notification content received in the BACKGROUND: " << payloadString.c_str() << std::endl;
std::cout << "\nPress 'Enter' to exit the App." << std::endl;
// Call Complete on the deferral when finished processing the payload.
// This removes the override that kept the app running even when the system was in a low power mode.
deferral.Complete();
std::cin.ignore();
}
break;
default:
std::cout << "\nUnexpected activation type" << std::endl;
std::cout << "\nPress 'Enter' to exit the App." << std::endl;
std::cin.ignore();
break;
}
}
Paso 6: Compilar e instalar la aplicación
Use Visual Studio para compilar e instalar la aplicación. Haga clic con el botón derecho en el archivo de solución en el Explorador de soluciones y seleccione Deploy. Visual Studio compilará la aplicación e la instalará en la máquina. Puede ejecutar la aplicación iniciandola a través del menú Inicio o el depurador de Visual Studio.
La consola del código del tutorial tendrá este aspecto:
Necesitará el token para enviar una notificación push a la aplicación.
Envío de una notificación push a la aplicación
En este momento, se completa toda la configuración y el servidor WNS puede enviar notificaciones push a las aplicaciones cliente. En los pasos siguientes, consulte los encabezados de solicitud y respuesta del servidor de notificaciones push y para más detalles.
Paso 1: Solicitar un token de acceso
Para enviar una notificación push, el servidor WNS primero debe solicitar un token de acceso. Envíe una solicitud HTTP POST con su Azure TenantId, Azure AppId y clave secreta. Para obtener información sobre cómo recuperar el Azure Tenant ID y el Azure App ID, consulte Obtener valores de la entidad e ID de la aplicación para iniciar sesión.
Solicitud de ejemplo HTTP:
POST /{tenantID}/oauth2/v2.0/token Http/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 160
grant_type=client_credentials&client_id=<Azure_App_Registration_AppId_Here>&client_secret=<Azure_App_Registration_Secret_Here>&scope=https://wns.windows.com/.default/
Solicitud de ejemplo de C#:
//Sample C# Access token request
var client = new RestClient("https://login.microsoftonline.com/{tenantID}/oauth2/v2.0");
var request = new RestRequest("/token", Method.Post);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("grant_type", "client_credentials");
request.AddParameter("client_id", "[Your app's Azure AppId]");
request.AddParameter("client_secret", "[Your app's secret]");
request.AddParameter("scope", "https://wns.windows.com/.default");
RestResponse response = await client.ExecutePostAsync(request);
Console.WriteLine(response.Content);
Si la solicitud se realiza correctamente, recibirá una respuesta que contiene el token en el campo access_token .
{
"token_type":"Bearer",
"expires_in":"86399",
"ext_expires_in":"86399",
"expires_on":"1653771789",
"not_before":"1653685089",
"access_token":"[your access token]"
}
Paso 2. Enviar una notificación sin procesar
Cree una solicitud HTTP POST que contenga el token de acceso que obtuvo en el paso anterior y el contenido de la notificación push que desea enviar. El contenido de la notificación push se entregará a la aplicación.
POST /?token=[The token query string parameter from your channel URL. E.g. AwYAAABa5cJ3...] HTTP/1.1
Host: dm3p.notify.windows.com
Content-Type: application/octet-stream
X-WNS-Type: wns/raw
Authorization: Bearer [your access token]
Content-Length: 46
{ Sync: "Hello from the Contoso App Service" }
var client = new RestClient("[Your channel URL. E.g. https://wns2-by3p.notify.windows.com/?token=AwYAAABa5cJ3...]");
var request = new RestRequest();
request.Method = Method.Post;
request.AddHeader("Content-Type", "application/octet-stream");
request.AddHeader("X-WNS-Type", "wns/raw");
request.AddHeader("Authorization", "Bearer [your access token]");
request.AddBody("Notification body");
RestResponse response = await client.ExecutePostAsync(request);");
Paso 3: Envío de una notificación de aplicación de origen en la nube
Si solo está interesado en enviar notificaciones sin procesar, omita este paso. Para enviar una notificación de aplicación basada en la nube, también conocida como notificación push, primero siga Inicio rápido: Notificaciones de aplicaciones en el SDK de aplicaciones de Windows. Las notificaciones de la aplicación pueden ser push (enviadas desde la nube) o enviarse localmente. El envío de una notificación de aplicación generada en la nube es similar al envío de una notificación sin procesar en el paso 2, excepto que el encabezado X-WNS-Type es toast, el Content-Type es text/xml, y el contenido contiene la carga XML de notificación de la aplicación. Consulte esquema XML de notificaciones para obtener más información sobre cómo construir la carga XML.
Cree una solicitud HTTP POST que contenga el token de acceso y el contenido de la notificación de aplicación de origen en la nube que desea enviar. El contenido de la notificación push se entregará a la aplicación.
POST /?token=AwYAAAB%2fQAhYEiAESPobjHzQcwGCTjHu%2f%2fP3CCNDcyfyvgbK5xD3kztniW%2bjba1b3aSSun58SA326GMxuzZooJYwtpgzL9AusPDES2alyQ8CHvW94cO5VuxxLDVzrSzdO1ZVgm%2bNSB9BAzOASvHqkMHQhsDy HTTP/1.1
Host: dm3p.notify.windows.com
Content-Type: text/xml
X-WNS-Type: wns/toast
Authorization: Bearer [your access token]
Content-Length: 180
<toast><visual><binding template="ToastGeneric"><text>Example cloud toast notification</text><text>This is an example cloud notification using XML</text></binding></visual></toast>
var client = new RestClient("https://dm3p.notify.windows.com/?token=AwYAAAB%2fQAhYEiAESPobjHzQcwGCTjHu%2f%2fP3CCNDcyfyvgbK5xD3kztniW%2bjba1b3aSSun58SA326GMxuzZooJYwtpgzL9AusPDES2alyQ8CHvW94cO5VuxxLDVzrSzdO1ZVgm%2bNSB9BAzOASvHqkMHQhsDy");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "text/xml");
request.AddHeader("X-WNS-Type", "wns/toast");
request.AddHeader("Authorization", "Bearer <AccessToken>");
request.AddParameter("text/xml", "<toast><visual><binding template=\"ToastGeneric\"><text>Example cloud toast notification</text><text>This is an example cloud notification using XML</text></binding></visual></toast>", ParameterType.RequestBody);
Console.WriteLine(response.Content);