我有一个第三方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" }
);
}