私が取り組んでいるC#単体テストアプリケーションがあります。関係するアセンブリは3つあります。C#アプリ自体のアセンブリ、アプリが使用する2番目のアセンブリ、2番目のアセンブリが使用する3番目のアセンブリです。
したがって、呼び出しは次のようになります。
First Assembly ------> Second Assembly---------> Third Assembly.
私が3番目の議会で行う必要があるのは、2番目の議会を呼び出した第1議会の名前を取得することです。
Assembly.GetExecutingAssembly().ManifestModule.Name
Assembly.GetCallingAssembly().ManifestModule.Name
2番目のアセンブリの名前を返します。そして
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.");
}
}
}
私はあなたがこのようにそれを行うことができるはずだと思います:
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クラス専用のバニラc.torをチェックしたい場合、これは興味深いことです。
これにより、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();
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\net-2.0\nunit-console.exe」がそれぞれ表示されます。
これを使用して私にとってはうまくいきました:
System.Reflection.Assembly.GetEntryAssembly().GetName()
呼び出しの順序に関係なく、最上位のアセンブリを見つける必要がある場合は、
Assembly.GetEntryAssembly()
特にユニットテストのコンテキストで実行する場合など、探しているものが完全にわかりません。
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")とほぼ同じ値を返す必要があります。
試してください:
Assembly.GetEntryAssembly().ManifestModule.Name
これは、プロセスを開始するために実際に実行されたアセンブリである必要があります。