Bloqueos de App Center (Windows)

Importante

Visual Studio App Center está programado para retirarse el 31 de marzo de 2025. Aunque puede seguir usando Visual Studio App Center hasta que se retire por completo, hay varias alternativas recomendadas a las que puede considerar la posibilidad de migrar.

Obtenga más información sobre las escalas de tiempo y las alternativas de soporte técnico.

Los bloqueos de App Center generarán automáticamente un registro de bloqueos cada vez que se bloquee la aplicación. El registro se escribe primero en el almacenamiento del dispositivo y, cuando el usuario vuelve a iniciar la aplicación, el informe de bloqueo se enviará a App Center.

El SDK de App Center solo recopila bloqueos causados por excepciones de .NET no controladas. No recopila bloqueos nativos, por ejemplo, al usar C o C++. Sin embargo, si tiene una aplicación con bloqueos de C++, puede cargarlas en App Center a través de la API de bloqueos de carga.

Siga el Introducción WPF/WinForms si aún no ha configurado el SDK en la aplicación.

Excepciones no controladas en aplicaciones winForms

Nota

Esta sección y las subsecciones siguientes solo se aplican a WinForms. Puede omitir esta sección si va a integrar el SDK en WPF.

De forma predeterminada, una excepción no controlada en una aplicación WinForms no desencadena un bloqueo (la aplicación no sale) si el depurador no está asociado.

En su lugar, Windows muestra un cuadro de diálogo al usuario la opción para continuar o salir de la ejecución de la aplicación. Por lo tanto, el SDK de App Center no puede capturar automáticamente estas excepciones (incluso si el usuario hace clic en el botón Salir ).

Los bloqueos se recopilan en App Center solo si hace que la aplicación se cierre automáticamente. App Center solo admite un bloqueo por sesión.

Hay dos maneras de notificar excepciones no controladas en WinForms. La aplicación se puede configurar para bloquearse en excepciones no controladas o continuar ejecutándose, pero notificar excepciones no controladas como errores en tiempo de ejecución.

Configuración de la aplicación para salir del bloqueo

Esta es la única manera de notificar la excepción no controlada como un bloqueo en App Center, hacer que la aplicación salga de las excepciones no controladas.

Para ello, llame a un método de Windows antes de inicializar el SDK:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
AppCenter.Start(...);

Si esta opción no es aceptable en la aplicación, puede notificar la excepción no controlada como un error en tiempo de ejecución (que se describe a continuación).

Notificar la excepción no controlada como un error en tiempo de ejecución

Si la aplicación debe seguir ejecutándose después de una excepción no controlada, no puede notificar la excepción como un bloqueo en App Center, pero en su lugar puede notificarla como un error.

Para ello, puede usar el ejemplo de código siguiente:

Application.ThreadException += (sender, args) =>
{
    Crashes.TrackError(args.Exception);
};
AppCenter.Start(...);

Nota

Cuando se adjunta el depurador, las excepciones no controladas harán que la aplicación salga (se bloquea) a menos que un controlador esté asociado a Application.ThreadException.

Generación de un bloqueo de prueba

App Center Crashes proporciona una API para generar un bloqueo de prueba para facilitar las pruebas del SDK. Esta API comprueba si hay configuraciones de depuración frente a versiones. Por lo tanto, solo puede usarlo al depurar, ya que no funcionará para las aplicaciones de lanzamiento.

Crashes.GenerateTestCrash();

Obtener más información sobre un bloqueo anterior

App Center Crashes tiene dos API que proporcionan más información en caso de que la aplicación se bloquee.

¿Se bloqueó la aplicación en la sesión anterior?

En cualquier momento después de iniciar el SDK, puede comprobar si la aplicación se bloqueó en el inicio anterior:

bool didAppCrash = await Crashes.HasCrashedInLastSessionAsync();

Esto resulta útil en caso de que quieras ajustar el comportamiento o la interfaz de usuario de la aplicación después de que se haya producido un bloqueo. Algunos desarrolladores eligen mostrar la interfaz de usuario adicional para disculparse a sus usuarios o quieren una manera de ponerse en contacto después de que se haya producido un bloqueo.

Nota

Este método solo se debe usar después Crashes de que se haya iniciado, siempre devolverá false antes del inicio.

Detalles sobre el último bloqueo

Si la aplicación se bloqueó anteriormente, puedes obtener detalles sobre el último bloqueo.

ErrorReport crashReport = await Crashes.GetLastSessionCrashReportAsync();

Nota

Este método solo se debe usar después Crashes de que se haya iniciado, siempre devolverá null antes del inicio.

Hay numerosos casos de uso para esta API, el más común es la gente que llama a esta API e implementa su delegado o agente de escucha personalizados crashes.

Personalización del uso de bloqueos de App Center

App Center Crashes proporciona devoluciones de llamada para que los desarrolladores realicen acciones adicionales antes y al enviar registros de bloqueo a App Center.

Nota

Establezca la devolución de llamada antes de llamar a AppCenter.Start(), ya que App Center inicia el procesamiento se bloquea inmediatamente después del inicio.

¿Se debe procesar el bloqueo?

Establezca esta devolución de llamada si desea decidir si es necesario procesar o no un bloqueo determinado. Por ejemplo, podría haber un bloqueo de nivel de sistema que le gustaría omitir y que no desea enviar a App Center.

Crashes.ShouldProcessErrorReport = (ErrorReport report) =>
{
    // Check the report in here and return true or false depending on the ErrorReport.
    return true;
};

Si la privacidad del usuario es importante para usted, es posible que quiera recibir la confirmación del usuario antes de enviar un informe de bloqueo a App Center. El SDK expone una devolución de llamada que indica a App Center Crashes que espere la confirmación del usuario antes de enviar los informes de bloqueo.

Si decide hacerlo, es responsable de obtener la confirmación del usuario, por ejemplo, a través de un mensaje de diálogo con una de las siguientes opciones: Enviar siempre, Enviar y No enviar. En función de la entrada, indicará a App Center qué hacer y, a continuación, se controlará el bloqueo en consecuencia.

Nota

El SDK no muestra un cuadro de diálogo para esto, la aplicación debe proporcionar su propia interfaz de usuario para solicitar el consentimiento del usuario.

Nota

La aplicación no debe llamar NotifyUserConfirmation explícitamente si no implementa un cuadro de diálogo de confirmación de usuario; el módulo Bloqueos controlará el envío de registros de forma implícita.

La siguiente devolución de llamada muestra cómo indicar al SDK que espere la confirmación del usuario antes de enviar bloqueos:

Crashes.ShouldAwaitUserConfirmation = () =>
{
    // Build your own UI to ask for user consent here. SDK doesn't provide one by default.

    // Return true if you built a UI for user consent and are waiting for user input on that custom UI, otherwise false.
    return true;
};

En caso de que se devuelva true en la devolución de llamada anterior, la aplicación debe obtener (con su propio código) el permiso de usuario y enviar un mensaje al SDK con el resultado mediante la SIGUIENTE API.

// Depending on the user's choice, call Crashes.NotifyUserConfirmation() with the right value.
Crashes.NotifyUserConfirmation(UserConfirmation.DontSend);
Crashes.NotifyUserConfirmation(UserConfirmation.Send);
Crashes.NotifyUserConfirmation(UserConfirmation.AlwaysSend);

Obtener información sobre el estado de envío de un registro de bloqueo

En ocasiones, quieres conocer el estado del bloqueo de la aplicación. Un caso de uso común es que es posible que quieras mostrar la interfaz de usuario que indica a los usuarios que la aplicación envía un informe de bloqueo o, en caso de que la aplicación se bloquee rápidamente después del inicio, quieres ajustar el comportamiento de la aplicación para asegurarte de que se pueden enviar los registros de bloqueo. Bloqueos de App Center proporciona tres devoluciones de llamada diferentes que puedes usar en la aplicación para recibir una notificación de lo que sucede:

La siguiente devolución de llamada se invocará antes de que el SDK envíe un registro de bloqueos.

Crashes.SendingErrorReport += (sender, e) =>
{
    // Your code, e.g. to present a custom UI.
};

En caso de que tengamos problemas de red o una interrupción en el punto de conexión y reinicie la aplicación, SendingErrorReport se desencadenará de nuevo después del reinicio del proceso.

La siguiente devolución de llamada se invocará después de que el SDK haya enviado correctamente un registro de bloqueo.

Crashes.SentErrorReport += (sender, e) =>
{
    // Your code, e.g. to hide the custom UI.
};

Se invocará la siguiente devolución de llamada si el SDK no pudo enviar un registro de bloqueos.

Crashes.FailedToSendErrorReport += (sender, e) =>
{
    // Your code goes here.
};

FailedToSendErrorReport Recibir significa que se ha producido un error no recuperable, como un código 4xx. Por ejemplo, 401 significa que es appSecret incorrecto.

Esta devolución de llamada no se desencadena si se trata de un problema de red. En este caso, el SDK sigue reintentando (y también pausa los reintentos mientras la conexión de red está inactiva).

Agregar datos adjuntos a un informe de bloqueo

Puede agregar datos adjuntos binarios y de texto a un informe de bloqueo. El SDK los enviará junto con el bloqueo para que pueda verlos en el portal de App Center. La siguiente devolución de llamada se invocará justo antes de enviar el bloqueo almacenado desde inicios de aplicación anteriores. No se invocará cuando se produzca el bloqueo. Asegúrese de que el archivo adjunto no tiene nombre minidump.dmp , ya que ese nombre está reservado para los archivos minivolcados. Este es un ejemplo de cómo adjuntar texto y una imagen a un bloqueo:

Crashes.GetErrorAttachments = (ErrorReport report) =>
{
    // Your code goes here.
    return new ErrorAttachmentLog[]
    {
        ErrorAttachmentLog.AttachmentWithText("Hello world!", "hello.txt"),
        ErrorAttachmentLog.AttachmentWithBinary(Encoding.UTF8.GetBytes("Fake image"), "fake_image.jpeg", "image/jpeg")
    };
};

Nota

El límite de tamaño es actualmente de 7 MB. Si intenta enviar datos adjuntos más grandes, se producirá un error.

Habilitar o deshabilitar bloqueos de App Center en tiempo de ejecución

Puede habilitar y deshabilitar bloqueos de App Center en tiempo de ejecución. Si la deshabilita, el SDK no hará ningún informe de bloqueos para la aplicación.

Crashes.SetEnabledAsync(false);

Para habilitar app Center Crashes de nuevo, use la misma API, pero pase true como parámetro.

Crashes.SetEnabledAsync(true);

No es necesario esperar esta llamada para que otras llamadas API (como IsEnabledAsync) sean coherentes.

El estado se conserva en el almacenamiento del dispositivo en los inicios de la aplicación.

Comprobación de si los bloqueos de App Center están habilitados

También puede comprobar si Los bloqueos de App Center están habilitados o no:

bool isEnabled = await Crashes.IsEnabledAsync();

Errores controlados

App Center también permite realizar un seguimiento de los errores mediante excepciones controladas. Para ello, use el TrackError método :

try {
    // your code goes here.
} catch (Exception exception) {
    Crashes.TrackError(exception);
}

Opcionalmente, una aplicación puede adjuntar propiedades a un informe de errores controlado para proporcionar más contexto. Pase las propiedades como un diccionario de pares clave-valor (solo cadenas) como se muestra en el ejemplo siguiente.

try {
    // your code goes here.
} catch (Exception exception) {
    var properties = new Dictionary<string, string>
    {
        { "Category", "Music" },
        { "Wifi", "On"}
    };
    Crashes.TrackError(exception, properties); 
}

También puede agregar datos adjuntos binarios y de texto a un informe de errores controlado. Pase los datos adjuntos como una matriz de ErrorAttachmentLog objetos como se muestra en el ejemplo siguiente.

try {
    // your code goes here.
} catch (Exception exception) {
    var attachments = new ErrorAttachmentLog[]
    {
        ErrorAttachmentLog.AttachmentWithText("Hello world!", "hello.txt"),
        ErrorAttachmentLog.AttachmentWithBinary(Encoding.UTF8.GetBytes("Fake image"), "fake_image.jpeg", "image/jpeg")
    };
    Crashes.TrackError(exception, attachments: attachments);
}