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

本文关键字:程序集 调用 获取 | 更新日期: 2023-09-27 18:36:57

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

所以调用是这样的:

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

在第三个程序集中,我需要做的是获取调用第二个程序集的拳头组件的名称。

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

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

Assembly.GetEntryAssembly().ManifestModule.Name

返回空

有谁知道是否有办法获得第一大会的程序集名称?

根据其他用户的要求,我在这里输入代码。这不是 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.");
        }
}
}

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

我想你应该可以这样做:

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的香草c.tor(如linq2db等),这很有趣。POCO类。

这将返回引用当前程序集的初始程序集。

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();

它使用这个对我有用:

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

Assembly.GetEntryAssembly() 如果也从 nunit-console 运行测试,则为 null。

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

 System.Diagnostics.Process.GetCurrentProcess().ProcessName 

 Environment.GetCommandLineArgs()[0];

对于 nunit-console,您将分别获得"nunit-console"和"C:''Program Files''NUnit 2.5.10''bin'et-2.0'unit-console.exe"。

尝试:

Assembly.GetEntryAssembly().ManifestModule.Name

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

不完全确定您要查找的内容,尤其是在单元测试的上下文中运行时,您最终会得到:

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);
}

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

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

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

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

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

这适用于在 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();