c# - reglamento - plan de trabajo de consejo de padres
C#Obtención de la Asamblea de padres Nombre de la Asamblea de llamada (10)
¿Qué hay de Assembly.GetEntryAssembly()
? Devuelve el ejecutable principal del proceso.
Process.GetCurrentProcess().MainModule.ModuleName
también debe devolver aproximadamente el mismo nombre que el nombre de ManifestModule ("yourapp.exe").
Tengo una aplicación de prueba de unidad C # en la que estoy trabajando. Hay tres conjuntos involucrados: el conjunto de la aplicación C #, el segundo conjunto que utiliza la aplicación y el tercero que utiliza el segundo.
Así que las llamadas van así:
First Assembly ------> Second Assembly---------> Third Assembly.
Lo que debo hacer en el tercer ensamblaje es obtener el nombre del ensamblaje de puño que llamó el segundo ensamblaje.
Assembly.GetExecutingAssembly().ManifestModule.Name
Assembly.GetCallingAssembly().ManifestModule.Name
Devuelve el nombre de la segunda asamblea. y
Assembly.GetEntryAssembly().ManifestModule.Name
devuelve NULL
¿Alguien sabe si hay una manera de llegar al nombre de la asamblea de la Primera Asamblea?
De acuerdo con la demanda de otros usuarios aquí pongo el código. Esto no es código 100%, pero sigue un código como este.
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);
}
}
}
y método de proyecto de prueba
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.");
}
}
}
Esto devolverá el ensamblaje inicial que hace referencia a su montaje actual.
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();
Esto funciona para obtener el ensamblaje original cuando se usan dos ensamblajes en una prueba NUnit, sin devolver un NULL. Espero que esto ayude.
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();
Funcionó para mí usando esto:
System.Reflection.Assembly.GetEntryAssembly().GetName()
No está completamente seguro de lo que está buscando, especialmente cuando ejecuta en el contexto de una prueba de unidad que terminará con:
mscorlib.dll
Microsoft.VisualStudio.TestPlatform.Extensions.VSTestIntegration.dll
(o algo similar dependiendo de su corredor de prueba) en el conjunto de ensamblajes que llevan a cualquier método a ser llamado.
El siguiente código imprime los nombres de cada uno de los ensamblajes involucrados en la llamada.
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);
}
Si conoce el número de cuadros en la pila, puede usar el objeto StackFrame y omitir el número del cuadro anterior.
// You skip 2 frames
System.Diagnostics.StackFrame stack = new System.Diagnostics.StackFrame(2, false);
string assemblyName = stack.GetMethod().DeclaringType.AssemblyQualifiedName;
Pero, si desea la primera llamada, necesita obtener todos los marcos y tomar la primera. (ver la solución AVee)
Si necesita encontrar el ensamblaje superior, independientemente del orden de llamada, puede usar
Assembly.GetEntryAssembly()
Supongo que deberías poder hacerlo así:
using System.Diagnostics;
using System.Linq;
...
StackFrame[] frames = new StackTrace().GetFrames();
string initialAssembly = (from f in frames
select f.GetMethod().ReflectedType.AssemblyQualifiedName
).Distinct().Last();
Esto le dará el ensamblaje que contiene el primer método que se inició por primera vez en el hilo actual. Entonces, si no está en el hilo principal, esto puede ser diferente del Ensamblaje de entradas, si entiendo su situación correctamente, este debería ser el ensamblaje que está buscando.
También puede obtener la Asamblea real en lugar de un nombre como este:
Assembly initialAssembly = (from f in frames
select f.GetMethod().ReflectedType.Assembly
).Distinct().Last();
Edición - a partir del 23 de septiembre de 2015
Por favor informa eso
GetMethod().ReflectedType
puede ser nulo, por lo que recuperar su AssemblyQualifiedName podría generar una excepción. Por ejemplo, eso es interesante si uno quiere verificar un c.tor de vainilla dedicado solo a una clase de POCO ORM (como linq2db, etc ...).
Tratar:
Assembly.GetEntryAssembly().ManifestModule.Name
Este debe ser el ensamblado que realmente se ejecutó para iniciar el proceso.
Assembly.GetEntryAssembly () es nulo si también ejecuta pruebas desde nunit-console .
Si solo desea el nombre de la aplicación en ejecución, use:
System.Diagnostics.Process.GetCurrentProcess().ProcessName
o
Environment.GetCommandLineArgs()[0];
Para nunit-console obtendría "nunit-console" y "C: / Archivos de programa / NUnit 2.5.10 / bin / net-2.0 / nunit-console.exe" respectivamente.