繁体   English   中英

列出来自 C# DLL 的类和函数头

[英]List classes and function headers from a C# DLL

我有一个第三方 C# DLL(被混淆了),我想使用pythonnet将它包装在 python 中。

到目前为止,我可以通过检查 Visual Studio 2017 中的 DLL 内容并逐个函数手动编写包装函数来做我想做的事情,并且有数百个。 我看不到在文本文件中列出或将我在 VS dll 资源管理器中看到的内容复制到文本文件以自动化包装任务的方法。

有没有办法将 .NET (C#) DLL 文件的内容列出为文本?

你可以试试这个。

使用反射和 CodeDom,此实现尝试为给定程序集中的所有类型、它们的属性和它们的方法生成空的主体源代码。

只需向PrintOutAssembly传递对混淆库的程序集的引用。

希望这可以帮助。

private static void PrintOutMethod(CodeTypeDeclaration codeTypeDeclaration, MethodInfo method)
{
    if (method.Name.StartsWith("get_") || method.Name.StartsWith("set_"))
    {
        return;
    }

    CodeMemberMethod codeMethod;

    codeTypeDeclaration.Members.Add
    (
        codeMethod = new CodeMemberMethod()
        {
            Name = method.Name,
            ReturnType = new CodeTypeReference(method.ReturnType),
            Attributes =
                (MemberAttributes.Public) |
                (method.IsFinal ? MemberAttributes.Final : MemberAttributes.Public) |
                (method.IsAbstract ? MemberAttributes.Abstract : MemberAttributes.Public) |
                (method.GetBaseDefinition() != null ? MemberAttributes.Override : MemberAttributes.Public)
        }
    );

    foreach (ParameterInfo parameter in method.GetParameters())
    {
        codeMethod.Parameters.Add
        (
            new CodeParameterDeclarationExpression()
            {
                Name = parameter.Name,
                Direction = parameter.IsIn && parameter.IsOut ? FieldDirection.Ref : parameter.IsOut ? FieldDirection.Out : FieldDirection.In,
                Type = new CodeTypeReference(parameter.ParameterType)
            }
        );
    }
}

private static void PrintOutProperty(CodeTypeDeclaration codeTypeDeclaration, PropertyInfo property)
{
    codeTypeDeclaration.Members.Add
    (
        new CodeMemberProperty()
        {
            Name = property.Name,
            Type = new CodeTypeReference(property.PropertyType),
            HasGet = property.GetMethod != null,
            HasSet = property.SetMethod != null,
            Attributes =
                (MemberAttributes.Public) |
                (property.GetMethod != null && property.GetMethod.IsFinal ? MemberAttributes.Final : MemberAttributes.Public) |
                (property.SetMethod != null && property.GetMethod.IsFinal ? MemberAttributes.Final : MemberAttributes.Public) |
                (property.GetMethod != null && property.GetMethod.IsAbstract ? MemberAttributes.Abstract : MemberAttributes.Public) |
                (property.SetMethod != null && property.GetMethod.IsAbstract ? MemberAttributes.Abstract : MemberAttributes.Public)
        }
    );
}

static Dictionary<string, CodeNamespace> namespaces = new Dictionary<string, CodeNamespace>();

private static void PrintOutType(System.CodeDom.CodeCompileUnit metaAssembly, CodeTypeDeclaration parentCodeTypeDeclaration, Type type)
{
    CodeNamespace codeNamespace;
    if (!namespaces.ContainsKey(type.Namespace))
    {
        namespaces[type.Namespace] = codeNamespace = new CodeNamespace(type.Namespace);
        metaAssembly.Namespaces.Add(codeNamespace);
    }
    else
    {
        codeNamespace = namespaces[type.Namespace];
    }

    CodeTypeDeclaration codeTypeDeclaration = new CodeTypeDeclaration(type.Name)
    {
        IsClass = type.IsClass,
        IsEnum = type.IsEnum,
        IsInterface = type.IsInterface,
        IsPartial = false,
        IsStruct = type.IsValueType && !type.IsEnum,
        Attributes = MemberAttributes.Public |
            (type.IsAbstract ? MemberAttributes.Abstract : MemberAttributes.Public) |
            (type.IsSealed ? MemberAttributes.Final : MemberAttributes.Public)
    };

    if (type.BaseType != null && type.BaseType != typeof(object))
    {
        codeTypeDeclaration.BaseTypes.Add(type.BaseType);
    }

    foreach (Type interfaceType in type.GetInterfaces())
    {
        codeTypeDeclaration.BaseTypes.Add(interfaceType);
    }

    if (parentCodeTypeDeclaration == null)
    {
        codeNamespace.Types.Add(codeTypeDeclaration);
    }
    else
    {
        parentCodeTypeDeclaration.Members.Add(codeTypeDeclaration);
    }

    foreach (Type nestedType in type.GetNestedTypes())
    {
        if (nestedType.IsPublic)
        {
            PrintOutType(metaAssembly, codeTypeDeclaration, nestedType);
        }
    }

    foreach (PropertyInfo publicProperty in type.GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance))
    {
        PrintOutProperty(codeTypeDeclaration, publicProperty);
    }

    foreach (MethodInfo publicMethod in type.GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance))
    {
        PrintOutMethod(codeTypeDeclaration, publicMethod);
    }
}

private static void PrintOutAssembly(Assembly assembly)
{
    Console.WriteLine("// Meta generation for assembly: {0}", assembly.FullName);

    System.CodeDom.CodeCompileUnit metaAssembly = new System.CodeDom.CodeCompileUnit();

    foreach (Type exportedType in assembly.GetExportedTypes())
    {
        PrintOutType(metaAssembly, null, exportedType);
    }

    System.CodeDom.Compiler.CodeDomProvider.CreateProvider("C#").GenerateCodeFromCompileUnit
    (
        metaAssembly,
        new StreamWriter(Console.OpenStandardOutput()),
        new System.CodeDom.Compiler.CodeGeneratorOptions() { BlankLinesBetweenMembers = true, IndentString = "    ", BracingStyle = "C" }
    );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM