C#获取调用程序集的父程序集名称

时间:2012-06-13 11:53:15

标签: c# .net reflection system.reflection

我有一个我正在研究的C#单元测试应用程序。涉及三个程序集 - C#app本身的程序集,应用程序使用的第二个程序集,以及第二个程序集使用的第三个程序集。

所以这些电话是这样的:

First Assembly ------> Second Assembly---------> Third Assembly.

我需要在第三个程序集中执行的操作是获取调用第二个程序集的Fist程序集的名称。

Assembly.GetExecutingAssembly().ManifestModule.Name
Assembly.GetCallingAssembly().ManifestModule.Name

返回第二个程序集的名称。 和

Assembly.GetEntryAssembly().ManifestModule.Name

返回NULL

有人知道是否有办法获得第一个集会的集会名称?

根据其他用户的要求,我放了代码。这不是100%的代码,而是遵循这样的代码。

namespace FirstAssembly{
public static xcass A
{
        public static Stream OpenResource(string name)
        {
            return Reader.OpenResource(Assembly.GetCallingAssembly(), ".Resources." + name);
        }
}
}

using FirstAssembly;
namespace SecondAssembly{
public static class B 

{
public static Stream FileNameFromType(string Name)

{
return = A.OpenResource(string name);
}
}
}

和测试项目方法

using SecondAssembly;
namespace ThirdAssembly{
public class TestC
{

 [TestMethod()]
        public void StremSizTest()
        {
            // ARRANGE
            var Stream = B.FileNameFromType("ValidMetaData.xml");
            // ASSERT
            Assert.IsNotNull(Stream , "The Stream  object should not be null.");
        }
}
}

9 个答案:

答案 0 :(得分:30)

我想你应该能够这样做:

using System.Diagnostics;
using System.Linq;

...

StackFrame[] frames = new StackTrace().GetFrames();
string initialAssembly = (from f in frames 
                          select f.GetMethod().ReflectedType.AssemblyQualifiedName
                         ).Distinct().Last();

这将使您获得包含首先在当前线程中启动的第一个方法的程序集。因此,如果您不在主线程中,这可能与EntryAssembly不同,如果我理解您的情况,那么这应该是您正在寻找的程序集。

你也可以得到实际的装配而不是这样的名字:

Assembly initialAssembly = (from f in frames 
                          select f.GetMethod().ReflectedType.Assembly
                         ).Distinct().Last();

编辑 - 截至2015年9月23日

请注意

GetMethod().ReflectedType

可以为null,因此检索其AssemblyQualifiedName可能会引发异常。 例如,如果想要检查仅专用于ORM(如linq2db等等)POCO类的vanilla c.tor,这很有意思。

答案 1 :(得分:11)

这将返回引用currentAssembly的初始Assembly。

var currentAssembly = Assembly.GetExecutingAssembly();
var callerAssemblies = new StackTrace().GetFrames()
            .Select(x => x.GetMethod().ReflectedType.Assembly).Distinct()
            .Where(x => x.GetReferencedAssemblies().Any(y => y.FullName == currentAssembly.FullName));
var initialAssembly = callerAssemblies.Last();

答案 2 :(得分:6)

如果您也从 nunit-console 运行测试,

Assembly.GetEntryAssembly()为null。

如果您只想要执行应用程序的名称,请使用:

 System.Diagnostics.Process.GetCurrentProcess().ProcessName 

 Environment.GetCommandLineArgs()[0];

对于 nunit-console ,您将分别获得“nunit-console”和“C:\ Program Files \ NUnit 2.5.10 \ bin \ net-2.0 \ nunit-console.exe”。 / p>

答案 3 :(得分:4)

使用它对我有用:

System.Reflection.Assembly.GetEntryAssembly().GetName()

答案 4 :(得分:0)

尝试:

Assembly.GetEntryAssembly().ManifestModule.Name

这应该是为了启动你的过程而实际执行的程序集。

答案 5 :(得分:0)

不完全确定你在寻找什么,特别是当你在单元测试的环境中运行时,你最终会遇到:

mscorlib.dll
Microsoft.VisualStudio.TestPlatform.Extensions.VSTestIntegration.dll

(或类似的东西,取决于你的测试运行器)在导致任何方法被调用的程序集中。

以下代码打印调用中涉及的每个程序集的名称。

var trace = new StackTrace();
var assemblies = new List<Assembly>();
var frames = trace.GetFrames();

if(frames == null)
{
    throw new Exception("Couldn't get the stack trace");
}

foreach(var frame in frames)
{
    var method = frame.GetMethod();
    var declaringType = method.DeclaringType;

    if(declaringType == null)
    {
        continue;
    }

    var assembly = declaringType.Assembly;
    var lastAssembly = assemblies.LastOrDefault();

    if(assembly != lastAssembly)
    {
        assemblies.Add(assembly);
    }
}

foreach(var assembly in assemblies)
{
    Debug.WriteLine(assembly.ManifestModule.Name);
}

答案 6 :(得分:0)

如果你知道堆栈中的帧数,你可以使用StackFrame对象并跳过前一帧的数量。

// You skip 2 frames
System.Diagnostics.StackFrame stack = new System.Diagnostics.StackFrame(2, false);
string assemblyName = stack.GetMethod().DeclaringType.AssemblyQualifiedName;

但是,如果你想要第一个电话,你需要获得所有帧并采取第一个。 (见AVee解决方案)

答案 7 :(得分:-1)

Assembly.GetEntryAssembly()怎么样?它返回进程的主要可执行文件。

Process.GetCurrentProcess().MainModule.ModuleName也应该返回与ManifestModule名称(“yourapp.exe”)相同的内容。

答案 8 :(得分:-3)

这适用于在NUnit测试中使用两个程序集时获取原始程序集,而不返回NULL。希望这会有所帮助。

var currentAssembly = Assembly.GetExecutingAssembly();
var callerAssemblies = new StackTrace().GetFrames()
        .Select(x => x.GetMethod().ReflectedType.Assembly).Distinct()
        .Where(x => x.GetReferencedAssemblies().Any(y => y.FullName ==     currentAssembly.FullName));
var initialAssembly = callerAssemblies.Last();