platform-compat icon indicating copy to clipboard operation
platform-compat copied to clipboard

With DE0002 How else are we going to be able to register the UnhandledException events on all platforms?

Open AraHaan opened this issue 5 years ago • 3 comments

With DE0002 being given to projects that uses using System.Security.Permissions; just to be able to register an unhandled exception event and to control appdomains (which registering that event requires). How else are we going to be able to use that event without using the CAS that is says not to use?

I think the documentation should include ways of using that event without using CAS then...

consider a minimal example being a console application like so:

  1. make a new console application dotnet new console and then add the package Microsoft.DotNet.Analyzers.Compatibility at version 0.2.12-alpha.
  2. Replace the Program.cs file with the following code:
using System;
using System.IO;
using System.Security.Permissions;
using System.Diagnostics;

namespace ConsoleApplication1
{
    public static class Program
    {
        [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
        public static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
            throw new Exception("Unhandled.")
        }

        private static void MyHandler(object sender, UnhandledExceptionEventArgs args)
        {
            // log the exception to a file.
            var e = (Exception)args.ExceptionObject;
            _ = Directory.CreateDirectory("logs");
            var text = string.Empty;
            text += e.GetType().Name + ": " + e.Message;
            text += e.StackTrace!;
            GetInnerException(text, e.InnerException);
            File.WriteAllText($"logs{Path.DirectorySeparatorChar}UnhandledExceptions.txt", text);
            Debug.WriteLine(e.GetType().Name + ": " + e.Message);
            Debug.WriteLine(e.StackTrace);
        }

        // this is to recurse and capture all inner exceptions.
        private static void GetInnerException(string? text, Exception? ex)
        {
            if (ex != null)
            {
                text += "Inner Exception:\n";
                text += ex.GetType().Name + ": " + ex.Message;
                text += ex.StackTrace!;
                Debug.WriteLine("Inner Exception:\n");
                Debug.WriteLine(ex.GetType().Name + ": " + ex.Message);
                Debug.WriteLine(ex.StackTrace);
                GetInnerException(text, ex.InnerException);
            }
        }
}

AraHaan avatar May 30 '20 02:05 AraHaan

Registering a handler for AppDomain.UnhandledException on .NET Framework does not require SecurityPermissionAttribute if the application domain already grants full trust to all assemblies; see AppDomain.IsFullyTrusted. So if you don't need to support partial-trust scenarios, you can delete that.

Your code sample seems to be using C# 8, which is not supported on .NET Framework anyway.

KalleOlaviNiemitalo avatar Jun 19 '20 20:06 KalleOlaviNiemitalo

https://github.com/dotnet/dotnet-api-docs/pull/4384 is removing the SecurityPermissionAttribute from the AppDomain.UnhandledException example.

KalleOlaviNiemitalo avatar Jun 19 '20 21:06 KalleOlaviNiemitalo

It is targeting .NET Core 3.1 and uses that to use that event for unhandled exceptions.

But I also plan to switch it to net5.0 eventually though.

AraHaan avatar Jun 19 '20 23:06 AraHaan