有了这个简单的C#代码,我就跑了csc hello.cs; ildasm /out=hello.txt hello.exe.
class Hello
{
public static void Main()
{
System.Console.WriteLine("hi");
}
}
Run Code Online (Sandbox Code Playgroud)
这是来自ildasm的IL代码.
.class private auto ansi beforefieldinit Hello
extends [mscorlib]System.Object
{
.method public hidebysig static void Main() cil managed
{
.entrypoint
// Code size 13 (0xd)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "hi"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ret
} // end of method Hello::Main
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7) …Run Code Online (Sandbox Code Playgroud) 我最近一直在挖掘IL,我注意到了C#编译器的一些奇怪的行为.以下方法是一个非常简单且可验证的应用程序,它将立即退出,退出代码为1:
static int Main(string[] args)
{
return 1;
}
Run Code Online (Sandbox Code Playgroud)
当我使用Visual Studio Community 2015编译它时,会生成以下IL代码(添加注释):
.method private hidebysig static int32 Main(string[] args) cil managed
{
.entrypoint
.maxstack 1
.locals init ([0] int32 V_0) // Local variable init
IL_0000: nop // Do nothing
IL_0001: ldc.i4.1 // Push '1' to stack
IL_0002: stloc.0 // Pop stack to local variable 0
IL_0003: br.s IL_0005 // Jump to next instruction
IL_0005: ldloc.0 // Load local variable 0 onto stack
IL_0006: ret // Return
}
Run Code Online (Sandbox Code Playgroud)
如果我要手写这个方法,看起来使用以下IL可以获得相同的结果:
.method …Run Code Online (Sandbox Code Playgroud) 我曾经能够ildasm在 Visual Studio 2017 的开发人员命令提示符中运行。使用 Visual Studio 2019,ildasm不再可用:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community>ildasm
'ildasm' is not recognized as an internal or external command,
operable program or batch file.
Run Code Online (Sandbox Code Playgroud)
是被其他东西替换了还是我的 VS 2019 安装不完整?
如果我是一个集会,那么ildasm仍然拆解它是否正常?
好.我编写了一个HelloWorld类库,随后的dll名为NGenILDasmTest.dll. - >针对.Net fw 4.
从Vs 2010命令提示符开始,我做到了
gacutil -i NGenILDasmTest.dll
Run Code Online (Sandbox Code Playgroud)
我可以看到GAC中安装的程序集.我跑了ildasm所以我可以查看IL.到现在为止还挺好.
然后我跑了
ngen NGenILDasmTest.dll
Run Code Online (Sandbox Code Playgroud)
(我没有为ngen指定任何选项).这个程序集成功编译完成.我找到了名称为NGenILDasmTest.ni.dll的文件夹
C:\Windows\Assembly\NativeImages_v4.0.30319_32\NGenILDasmTest\81d49dd4c7df22fb3df530402b58ffc9
Run Code Online (Sandbox Code Playgroud)
现在,当我像下面一样运行ildasm时
ildasm "C:\Windows\Assembly\NativeImages_v4.0.30319_32\NGenILDasmTest\81d49dd4c7df22fb3df530402b58ffc9\NGenILDasmTest.ni.dll"
Run Code Online (Sandbox Code Playgroud)
我可以看到Ngen-ed组件的内容.这是正常的吗?
从技术上讲,Ngen为IL生成本机CPU插件(并且显然将其置于C:\ windows\Assembly\NAtiveImages_V4.##### _ 32 - 在我的情况下).如果是这种情况,我怎么能使用ILDasm将NGen-ed程序集看作IL?
请帮助我理解我在这里缺少的"小东西".
有没有办法以编程方式获取ildasm.exe/ilasm.exe可执行文件的FileInfo/Path?我正在尝试反编译并重新编译一个dll/exe文件后对其进行一些修改(我猜测PostSharp会做类似的事情,在编译后改变IL).
我发现了一篇博文,指出:
var pfDir = Environment.GetFolderPath(Environment.SpecialFolders.ProgramFiles));
var sdkDir = Path.Combine(pfDir, @"Microsoft SDKs\Windows\v6.0A\bin");
...
Run Code Online (Sandbox Code Playgroud)
但是,当我运行此代码时,目录不存在(主要是因为我的SDK版本是7.1),所以在我的本地机器上正确的路径是@"Microsoft SDKs\Windows\v7.1\bin".我怎样才能确保我能找到ildasm.exe?
同样,我发现了另一篇关于如何访问ilasm.exe的博文:
string windows = Environment.GetFolderPath(Environment.SpecialFolder.System);
string fwork = Path.Combine(windows, @"..\Microsoft.NET\Framework\v2.0.50727");
...
Run Code Online (Sandbox Code Playgroud)
虽然这有效,但我注意到我有Framework和Framework64,而在Framework本身中我拥有v4.0.30319的所有版本(与Framework64相同).那么,我怎么知道使用哪一个?它应该基于我正在瞄准的.NET Framework版本吗?
摘要:
.NET Core中*deps.json文件的用途是什么?在此类文件中存储引用而不在程序集清单中存储引用的原因是什么(如在独立的.NET Framework中)?
使用Ildasm我检查了程序集清单在dotnet构建命令之后不包含这些依赖项的条目.
但是在dotnet发布命令之后它有条目.
TypedReference和ArgIterator?)?我怀疑它在编译器中是硬编码的,因为错误CS0610的文档指出:
有些类型不能用作字段或属性.这些类型包括......
在我看来哪些类型可以扩展 - 但我可能是错的.
我在SO上搜索了一下,虽然我明白以编程方式抛出编译器错误无法完成,但我找不到任何来源说明某些"特殊"类型的行为无法复制.
即使问题主要是学术问题,也可能会有一些答案.例如,有时可以确保某个对象的生命周期被约束到创建它的方法块.
编辑: RuntimeArgumentHandle是一种(未提及)不可存储的类型.
编辑2:如果它可以有任何用途,似乎CLR也以不同的方式处理这些类型,如果不仅仅是编译器(仍然假设类型与其他类型没有任何区别).例如,以下程序将提出一个TypeLoadException问题TypedReference*.我已经对它进行了调整以缩短它,但你可以随心所欲地解决它.例如,void*将指针的类型更改为不会抛出异常.
using System;
unsafe static class Program
{
static TypedReference* _tr;
static void Main(string[] args)
{
_tr = (TypedReference*) IntPtr.Zero;
}
}
Run Code Online (Sandbox Code Playgroud) 是否有.net-core的ILDASM/ILASM等价物?
具体来说,我正在寻找在Linux上运行的东西(因此为什么是.net-core).
我在尝试使用 Visual Studio 命令提示符(反)组装 dll 时遇到了困难,看起来不像我在 microsoft page 中看到的那么简单。
我正在以这些方式使用 ildasm:
ildasm myLibrary.dll output:MyLibrary.il
Run Code Online (Sandbox Code Playgroud)
我得到:无法打开“MyLibrary.il”进行输出。
我也试过完整路径:
ildasm directory\myLibrary.dll output:directory\MyLibrary.il
Run Code Online (Sandbox Code Playgroud)
我得到:指定的多个输入文件
使用 ildasm GUI 实际上有效,但是当我使用 ilasm 时:
ilasm myLibrary.il /dll
Run Code Online (Sandbox Code Playgroud)
我得到:无法打开 'myLibrary.il',当我使用完整路径时,我得到了同样的错误。
这里有什么问题?