gpt4 book ai didi

c# - 在构建过程中找出 PlatformNotSupportedException

转载 作者:太空狗 更新时间:2023-10-29 20:12:23 26 4
gpt4 key购买 nike

我正在使用 .NET Core 2.2Windows 开发一个项目。明年我将在 Linux 上构建并支持它。我正在寻找一种方法来标记错误并在代码中使用 PlatformNotSupportedException 时中断构建。

我看过 .NET API analyzer仍处于预发布阶段,自去年以来未更新。

最佳答案

您可以使用 Mono.Cecil 检查程序集中某处是否抛出异常。

public static class ExceptionHelper<TException> where TException : Exception
{
private static readonly string typeName = typeof(TException).FullName;

public static void ThrowIfDetected(Assembly assembly)
{
var definition = AssemblyDefinition.ReadAssembly(assembly.Location);
var exceptions = CreateExceptions(definition);
if (exceptions.Any())
throw new AggregateException(exceptions);
}

public static void ThrowIfDetected(params Assembly[] assemblies) =>
ThrowIfDetected(assemblies as IEnumerable<Assembly>);

public static void ThrowIfDetected(IEnumerable<Assembly> assemblies)
{
var exceptions = CreateExceptions(assemblies);
if (exceptions.Any())
throw new AggregateException(exceptions);
}

private static IEnumerable<Exception> CreateExceptions(IEnumerable<Assembly> assemblies) =>
assemblies.Select(assembly => AssemblyDefinition.ReadAssembly(assembly.Location))
.SelectMany(definition => CreateExceptions(definition));

private static IEnumerable<Exception> CreateExceptions(AssemblyDefinition definition)
{
var methods =
definition.Modules
.SelectMany(m => m.GetTypes())
.SelectMany(t => t.Methods)
.Where(m => m.HasBody);
foreach (var method in methods)
{
var instructions = method.Body.Instructions
.Where(i => i.OpCode.Code == Code.Newobj && // new object is created
((MethodReference)i.Operand).DeclaringType.FullName == typeName && // the object is 'TException'
i.Next.OpCode.Code == Code.Throw); // and it's immediately thrown
foreach (var i in instructions)
{
var message = $"{definition.FullName} {method.FullName} offset {i.Offset} throws {typeName}";
yield return new Exception(message);
}
}
}
}

要获取引用的程序集,请使用这样的扩展方法:

public static class AssemblyExtensions
{
public static Assembly[] ReflectionOnlyLoadReferencedAssemblies(this Assembly assembly) =>
assembly.GetReferencedAssemblies()
.Select(a => Assembly.ReflectionOnlyLoad(a.FullName))
.ToArray();
}

用法:

创建一个新的控制台应用程序并使用上述代码添加对程序集的引用。尝试:

try
{
ExceptionHelper<PlatformNotSupportedException>.ThrowIfDetected(Assembly.GetEntryAssembly().ReflectionOnlyLoadReferencedAssemblies());
}
catch(AggregateException e)
{
foreach (var inner in e.InnerExceptions)
Console.WriteLine($"{inner.Message}\n");
}

它给出:

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Void System.Environment::SetEnvironmentVariable(System.String,System.String) offset 82 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.String System.Environment::InternalGetFolderPath(System.Environment/SpecialFolder,System.Environment/SpecialFolderOption,System.Boolean) offset 75 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Void System.Security.Principal.SecurityIdentifier::.ctor(System.Security.Principal.WellKnownSidType,System.Security.Principal.SecurityIdentifier) offset 49 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Int32 System.Security.Principal.Win32::CreateWellKnownSid(System.Security.Principal.WellKnownSidType,System.Security.Principal.SecurityIdentifier,System.Byte[]&) offset 17 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Boolean System.Security.Principal.Win32::IsEqualDomainSid(System.Security.Principal.SecurityIdentifier,System.Security.Principal.SecurityIdentifier) offset 17 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Int32 System.Security.Principal.Win32::GetWindowsAccountDomainSid(System.Security.Principal.SecurityIdentifier,System.Security.Principal.SecurityIdentifier&) offset 17 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Boolean System.Security.Principal.Win32::IsWellKnownSid(System.Security.Principal.SecurityIdentifier,System.Security.Principal.WellKnownSidType) offset 17 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.IntPtr System.StubHelpers.HStringMarshaler::ConvertToNative(System.String) offset 17 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.IntPtr System.StubHelpers.HStringMarshaler::ConvertToNativeReference(System.String,System.Runtime.InteropServices.WindowsRuntime.HSTRING_HEADER*) offset 17 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.String System.StubHelpers.HStringMarshaler::ConvertToManaged(System.IntPtr) offset 17 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Void System.StubHelpers.SystemTypeMarshaler::ConvertToNative(System.Type,System.StubHelpers.TypeNameNative*) offset 17 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Void System.StubHelpers.SystemTypeMarshaler::ConvertToManaged(System.StubHelpers.TypeNameNative*,System.Type&) offset 17 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Int32 System.StubHelpers.HResultExceptionMarshaler::ConvertToNative(System.Exception) offset 17 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Exception System.StubHelpers.HResultExceptionMarshaler::ConvertToManaged(System.Int32) offset 17 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.IntPtr System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal::StringToHString(System.String) offset 17 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.String System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal::PtrToStringHString(System.IntPtr) offset 17 throws System.PlatformNotSupportedException

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Void System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal::FreeHString(System.IntPtr) offset 17 throws System.PlatformNotSupportedException

现在您可以在单元测试中使用它(例如使用 NUnit)来自动检查您引用的程序集是否可以抛出 PlatformNotSupportedException

[TestFixture]
public class Tests
{
[Test]
public void ReferencedAssembliesDoNOtThrowPlatformNotSupportedException()
{
Assert.DoesNotThrow(() => ExceptionHelper<PlatformNotSupportedException>.ThrowIfDetected(yourAssembly.ReflectionOnlyLoadReferencedAssemblies()));
}
}

如果测试像描述的那样失败,则中断构建 here .

关于c# - 在构建过程中找出 PlatformNotSupportedException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57321340/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com