[英]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.