所以我在C#中是一个相当中级的程序员,最近我一直沉迷于文件大小并创建可用的最小文件。为此,我意识到将MSIL用于更简单的程序可以减少大小。
所以我尝试转换以下内容
现在,在做完之后我想...为什么在我可以简单地使用反射并在必须使用磁盘的情况下运行它们时编写文件?
这就是问题出现的地方,我无法找到解决方案。
此代码有什么问题?
.assembly a{}
.subsystem 0x0002
.class private AA1.B
extends [mscorlib]System.Object{
.method private static void a(){
.entrypoint
.maxstack 4
.locals init (
[0] string str,
[1] uint8[] buffer)
nop
newobj instance void [System]System.Net.WebClient::.ctor()
ldstr "http://www.mywebwiste.com/myDotNetFile.exe"
call instance uint8[] [System]System.Net.WebClient::DownloadData(string)
stloc.1
ldloc.1
call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::Load(uint8[])
callvirt instance class [mscorlib]System.Reflection.MethodInfo [mscorlib]System.Reflection.Assembly::get_EntryPoint()
ldnull
ldc.i4.0
newarr object
callvirt instance object [mscorlib]System.Reflection.MethodBase::Invoke(object, object[])
}}
我编译的错误是“引用未声明的extern Assembly System”。和“参考未申报的外部组件mscorlib”。我不是在宣布他们吗?它仍然可以编译它们,但在运行时它只会崩溃。
答案 0 :(得分:3)
我编译的错误是"参考未声明的extern Assembly System。"和"参考未申报的外部组件mscorlib"。
这些不是错误,而是警告,我收到警告的完整信息是:
警告:引用未声明的extern程序集' mscorlib'。尝试自动检测
要删除警告,您需要声明程序集:
.assembly extern mscorlib
{
.ver 4:0:0:0
.publickeytoken = (B7 7A 5C 56 19 34 E0 89)
}
.assembly extern System
{
.ver 4:0:0:0
.publickeytoken = (B7 7A 5C 56 19 34 E0 89)
}
但这不是你的实际问题。如果我运行已编译的程序集,它确实崩溃了。使用Visual Studio实时调试程序,您会发现异常是:
System.InvalidProgramException:公共语言运行时检测到无效程序。
这很可能意味着您的IL错误,并且您应该在其上运行PEVerify。如果您这样做,则会收到此错误:
错误:[AA1.B::a] [offset 0x00000023]在方法结束时没有返回
这意味着您需要在方法结束时添加ret
。如果你解决了这个问题,你会得到:
错误:[AA1.B::a] [offset 0x00000028]从void函数返回时,堆栈必须为空。
这意味着您需要pop
从object
返回的MethodBase::Invoke
。
如果你解决了这个问题,你就不会再收到任何PEVerify错误,而且你的代码可能会有效。