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.");
}
}
}
我想你应该可以这样做:
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();