代码之家  ›  专栏  ›  技术社区  ›  laktak

需要工具来转储程序集的引用类型和成员

  •  0
  • laktak  · 技术社区  · 15 年前

    我需要一个工具,可以以机器可读的格式转储程序集使用的引用类型。

    例如,程序集“dummy.exe”中的此代码

    static void Main()
    {
      Console.WriteLine("Hello World");
    }
    

    会产生类似

    <references assembly="dummy.exe">
      <mscorlib>
        <System.Console>
          <WriteLine/>
    ...
    

    你能用反光镜吗?

    2 回复  |  直到 15 年前
        1
  •  0
  •   Dirk Vollmar    15 年前

    反射镜能够显示进口的类型和组件。右键单击程序集并选择 分析 从上下文菜单。然后,您可以展开生成的树视图,并复制依赖项的文本表示形式(但没有XML,只是简单的纯文本)。例如,对于 演示核心 您将得到的程序集(并非所有引用都在下面的示例中展开):

    PresentationCore
      Depends On
        Microsoft.VisualC
            Microsoft.VisualC.DebugInfoInPDBAttribute..ctor()
            Microsoft.VisualC.MiscellaneousBitsAttribute..ctor(Int32)
        mscorlib
        PresentationCFFRasterizer
        System
        System.Deployment
        System.Drawing
        System.Xml
        UIAutomationProvider
        UIAutomationTypes
        WindowsBase
      P/Invoke Imports
        ADVAPI32.dll
            <Module>.CloseServiceHandle(SC_HANDLE__*) : Int32 modopt(CallConvStdcall)
            <Module>.CreateWellKnownSid(WELL_KNOWN_SID_TYPE, Void*, Void*, UInt32 modopt(IsLong)*) : Int32 modopt(CallConvStdcall)
            <Module>.InitializeSecurityDescriptor(Void*, UInt32 modopt(IsLong)) : Int32 modopt(CallConvStdcall)
            <Module>.OpenSCManagerW(UInt16 modopt(IsConst)*, UInt16 modopt(IsConst)*, UInt32 modopt(IsLong)) : SC_HANDLE__* modopt(CallConvStdcall)
            <Module>.OpenServiceW(SC_HANDLE__*, UInt16 modopt(IsConst)*, UInt32 modopt(IsLong)) : SC_HANDLE__* modopt(CallConvStdcall)
            <Module>.QueryServiceStatus(SC_HANDLE__*, _SERVICE_STATUS*) : Int32 modopt(CallConvStdcall)
            <Module>.RegCloseKey(HKEY__*) : Int32 modopt(IsLong) modopt(CallConvStdcall)
            <Module>.RegOpenKeyExW(HKEY__*, UInt16 modopt(IsConst)*, UInt32 modopt(IsLong), UInt32 modopt(IsLong), HKEY__**) : Int32 modopt(IsLong) modopt(CallConvStdcall)
            <Module>.RegQueryInfoKeyW(HKEY__*, UInt16*, UInt32 modopt(IsLong)*, UInt32 modopt(IsLong)*, UInt32 modopt(IsLong)*, UInt32 modopt(IsLong)*, UInt32 modopt(IsLong)*, UInt32 modopt(IsLong)*, UInt32 modopt(IsLong)*, UInt32 modopt(IsLong)*, UInt32 modopt(IsLong)*, _FILETIME*) : Int32 modopt(IsLong) modopt(CallConvStdcall)
            <Module>.RegQueryValueExW(HKEY__*, UInt16 modopt(IsConst)*, UInt32 modopt(IsLong)*, UInt32 modopt(IsLong)*, Byte*, UInt32 modopt(IsLong)*) : Int32 modopt(IsLong) modopt(CallConvStdcall)
            <Module>.SetSecurityDescriptorDacl(Void*, Int32, _ACL*, Int32) : Int32 modopt(CallConvStdcall)
            <Module>.SetSecurityDescriptorSacl(Void*, Int32, _ACL*, Int32) : Int32 modopt(CallConvStdcall)
            <Module>.StartServiceW(SC_HANDLE__*, UInt32 modopt(IsLong), UInt16 modopt(IsConst)**) : Int32 modopt(CallConvStdcall)
        KERNEL32.dll
        mscms.dll
        mshwgst.dll
        MSVCR80.dll
        ntdll.dll
        ole32.dll
        penimc.dll
        PresentationNative_v0300.dll
        shfolder.dll
        urlmon.dll
        user32.dll
        WindowsCodecs.dll
        WindowsCodecsExt.dll
        wpfgfx_v0300.dll
    
        2
  •  0
  •   Marc Gravell    15 年前

    获取引用的 类型和成员 对于任意程序集 极其 很难;你需要一个深度的IL工具-基本上是反射镜。获取参考资料 组件 (并观察循环参考,其中 可能),比如:

    static void Main() {
        WriteReferences(Assembly.GetEntryAssembly());        
    }
    static void WriteReferences(Assembly assembly) {
        HashSet<string> done = new HashSet<string>();
        Queue<AssemblyName> pending = new Queue<AssemblyName>();
        foreach (var name in assembly.GetReferencedAssemblies()) {
            pending.Enqueue(name);
        }
        while(pending.Count > 0) {
            var name = pending.Dequeue();
            string s = name.FullName;
            if (done.Add(s)) {
                Console.WriteLine(s);
                try {
                    Assembly asm = Assembly.Load(name);
                    foreach (var next in asm.GetReferencedAssemblies()) {
                        pending.Enqueue(next);
                    }
                }
                catch { }
            }
        }
    }