39

我有一个正在开发的 C# 单元测试应用程序。涉及三个程序集 - C# 应用程序本身的程序集、应用程序使用的第二个程序集和第二个程序使用的第三个程序集。

所以电话是这样的:

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

在第三个程序集中我需要做的是获取称为第二个程序集的拳头程序集的名称。

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.");
        }
}
}
4

9 回答 9

42

我想你应该可以这样做:

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,那就很有趣了。

于 2012-06-21T15:14:08.877 回答
16

这将返回引用您 currentAssembly 的初始程序集。

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();
于 2014-01-28T19:32:12.600 回答
11

它对我有用:

System.Reflection.Assembly.GetEntryAssembly().GetName()
于 2016-12-19T18:48:50.017 回答
7

如果您也从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”。

于 2012-06-22T05:05:15.873 回答
2

尝试:

Assembly.GetEntryAssembly().ManifestModule.Name

这应该是实际执行以启动您的流程的程序集。

于 2012-06-13T11:56:14.360 回答
0

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

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

但是,如果您想要第一次调用,则需要获取所有帧并获取第一个。(参见 AVee 解决方案)

于 2012-06-22T11:12:17.900 回答
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);
}
于 2012-06-21T08:47:23.170 回答
-1

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

Process.GetCurrentProcess().MainModule.ModuleName还应该返回与 ManifestModule 名称(“yourapp.exe”)大致相同的值。

于 2012-06-13T11:56:13.800 回答
-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();
于 2015-04-15T19:52:41.180 回答