您好我写了以下代码:
AssemblyName assemblyName = new AssemblyName("SamAsm");
AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
TypeBuilder typeBuilder = assemblyBuilder.DefineDynamicModule("SamAsm.exe").DefineType("SamAsmType", TypeAttributes.Public);
MethodBuilder methodBuilder1 = typeBuilder.DefineMethod("Main", MethodAttributes.Static | MethodAttributes.Public, typeof(void), new Type[] { typeof(string) });
ILGenerator gen = methodBuilder1.GetILGenerator();
FieldInfo field1 = typeof(Form1).GetField("TextBox1", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo method2 = typeof(Control).GetProperty("Text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetGetMethod();
MethodInfo method3 = typeof(String).GetMethod(
"op_Equality",
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
null,
new Type[]{
typeof(String),
typeof(String)
},
null
);
MethodInfo method4 = typeof(MessageBox).GetMethod(
"Show",
BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic,
null,
new Type[]{
typeof(String)
},
null
);
LocalBuilder a = gen.DeclareLocal(typeof(Boolean));
System.Reflection.Emit.Label label42 = gen.DefineLabel();
gen.Emit(OpCodes.Nop);
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldfld, field1);
gen.Emit(OpCodes.Callvirt, method2);
gen.Emit(OpCodes.Ldstr, "HI");
gen.Emit(OpCodes.Call, method3);
gen.Emit(OpCodes.Ldc_I4_0);
gen.Emit(OpCodes.Ceq);
gen.Emit(OpCodes.Stloc_0);
gen.Emit(OpCodes.Ldloc_0);
gen.Emit(OpCodes.Brtrue_S, label42);
gen.Emit(OpCodes.Nop);
gen.Emit(OpCodes.Ldstr, "You cracked me");
gen.Emit(OpCodes.Call, method4);
gen.Emit(OpCodes.Pop);
gen.Emit(OpCodes.Nop);
gen.MarkLabel(label42);
gen.Emit(OpCodes.Ret);
typeBuilder.CreateType().GetMethod("Main").Invoke(null, new string[] { null });
assemblyBuilder.SetEntryPoint(methodBuilder1, PEFileKinds.WindowApplication);}
当我尝试这个时,它会阻止我 gen.Emit(OpCodes.Ldfld,typeof(Form1).GetField(“TextBox1”,BindingFlags.Public | BindingFlags.NonPublic));
并告诉:该值不能为null。参数名称:con。 有人可以帮帮我吗?
答案 0 :(得分:2)
以下似乎很有可能返回null
:
typeof(Form1).GetField("TextBox1", BindingFlags.Public | BindingFlags.NonPublic)
我的直接猜测是你需要在标志集中添加BindingFlags.Instance
才能返回该字段。
答案 1 :(得分:2)
这意味着调用的其中一个参数为null,很可能是 typeof(Form1)的返回值.GetField(“TextBox1”,BindingFlags.Public | BindingFlags.NonPublic)。 / p>
由于您已将该值存储在变量 field1 中,因此应进入调试模式并检查它是否为空。
如果值为null,则表示不同的含义:
在您的情况下,如果您查看GetField的MSDN documentation,则会明确说明:
以下BindingFlags过滤器标志可用于定义要包含在搜索中的字段:
您必须指定BindingFlags.Instance或BindingFlags.Static才能获得回复。
指定BindingFlags.Public以在搜索中包含公共字段。
指定BindingFlags.NonPublic以在搜索中包含非公共字段(即私有,内部和受保护字段)。
指定BindingFlags.FlattenHierarchy以在层次结构中包含公共和受保护的静态成员;不包括继承类中的私有静态成员。
所以你应该使用 BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance 而不是 BindingFlags.Public | BindingFlags.NonPublic
同时替换
gen.Emit(OpCodes.Ldfld,typeof(Form1).GetField("TextBox1", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
用
gen.Emit(OpCodes.Ldfld, field1);
并在您指定field1的行上使用正确的标记。
更新:您对Main的最终通话存在同样的问题。您需要在以下代码行中指定BindingFlags.Static,您可以使用代码中前面的MethodAttributes将方法定义为静态:
typeBuilder.CreateType().GetMethod("Main", BindingFlags.Static | BindingFlags.Public).Invoke(null, new string[] { null });
另外,您不希望以您的方式检索属性访问器:您应该使用GetProperty来代替使用具有访问者名称的GetMethod(get_Text):
MethodInfo method2 = typeof(Control).GetProperty("Text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetMethod;
希望有所帮助。