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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11014280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 16:07:18  来源:igfitidea点击:

C# Getting Parent Assembly Name of Calling Assembly

c#.netreflectionsystem.reflection

提问by Saroop Trivedi

I've got a C# unit test application that I'm working on. There are three assemblies involved - the assembly of the C# app itself, a second assembly that the app uses, and a third assembly that's used by the second one.

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

So the calls go like this:

所以电话是这样的:

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

What I need to do in the third assembly is get the name of the Fist Assembly that called the second assembly.

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

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

returns the name of the Second assembly. and

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

Assembly.GetEntryAssembly().ManifestModule.Name

return NULL

返回 NULL

Does anybody know if there is a way to get to the assembly name of the First Assembly?

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

As per the other users demand here I put the code. This is not 100% code but follow of code like this.

根据其他用户的需求,我把代码放在这里。这不是 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);
}
}
}

and Test project method

和测试项目方法

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

回答by Botz3000

How about Assembly.GetEntryAssembly()? It returns the main executable of the process.

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

Process.GetCurrentProcess().MainModule.ModuleNameshould also return about the same as the ManifestModule name ("yourapp.exe").

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

回答by Jon Egerton

Try:

尝试:

Assembly.GetEntryAssembly().ManifestModule.Name

This should be the assembly that was actually executed to start your process.

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

回答by mlorbetske

Not completely sure what you're looking for, especially as when running in the context of a unit test you'll wind up with:

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

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

(or something similar depending on your test runner) in the set of assemblies that lead to any method being called.

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

The below code prints the names of each of the assemblies involved in the call.

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

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

回答by AVee

I guess you should be able to do it like this:

我想你应该可以这样做:

using System.Diagnostics;
using System.Linq;

...

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

This will get you the Assembly which contains the first method which was started first started in the current thread. So if you're not in the main thread this can be different from the EntryAssembly, if I understand your situation correctly this should be the Assembly your looking for.

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

You can also get the actual Assembly instead of the name like this:

您还可以获得实际的程序集而不是像这样的名称:

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

Edit - as of Sep. 23rd, 2015

编辑 - 截至 2015 年 9 月 23 日

Please, notice that

请注意

GetMethod().ReflectedType

can be null, so retrieving its AssemblyQualifiedName could throw an exception. For example, that's interesting if one wants to check a vanilla c.tor dedicated only to an ORM (like linq2db, etc...) POCO class.

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

回答by tymtam

Assembly.GetEntryAssembly()is null if you run tests from nunit-consoletoo.

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

If you just want the name of the executing app then use:

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

 System.Diagnostics.Process.GetCurrentProcess().ProcessName 

or

或者

 Environment.GetCommandLineArgs()[0];

For nunit-consoleyou would get "nunit-console" and "C:\Program Files\NUnit 2.5.10\bin\net-2.0\nunit-console.exe" respectively.

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

回答by Hyralex

If you know the number of frame in the stack, you can use the StackFrame object and skip the number of previous frame.

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

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

But, if you want the first call, you need to get all frames and take the first. (see AVee solution)

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

回答by realstrategos

This will return the the initial Assembly that references your 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();

回答by user4793658

This works for getting the original assembly when using two assemblies in an NUnit test, without returning a NULL. Hope this helps.

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

回答by Marcello

It worked for me using this:

它对我有用:

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