with net method español create c# .net reflection

c# - net - ¿Cómo obtengo la ruta del ensamblaje en el que se encuentra el código?



reflection c# español (27)

¿Aplicación web?

Server.MapPath("~/MyDir/MyFile.ext")

¿Hay alguna forma de obtener la ruta para el ensamblaje en el que reside el código actual? No quiero la ruta del ensamblado de llamada, solo la que contiene el código.

Básicamente, mi prueba de unidad necesita leer algunos archivos de prueba xml que se encuentran en relación con la dll. Quiero que la ruta siempre se resuelva correctamente, independientemente de si la dll de prueba se ejecuta desde TestDriven.NET, la GUI de MbUnit o algo más.

Edit : La gente parece estar malinterpretando lo que estoy preguntando.

Mi biblioteca de prueba se encuentra en decir

C: / projects / myapplication / daotests / bin / Debug / daotests.dll

y me gustaría conseguir este camino:

C: / projects / myapplication / daotests / bin / Debug /

Las tres sugerencias hasta el momento me fallan cuando corro desde la MbUnit Gui:

  • Environment.CurrentDirectory proporciona c: / Archivos de programa / MbUnit

  • System.Reflection.Assembly.GetAssembly(typeof(DaoTests)).Location muestra C: / Documents and Settings / george / Local Settings / Temp / .... / DaoTests.dll

  • System.Reflection.Assembly.GetExecutingAssembly().Location da lo mismo que la anterior.


¿Esto ayuda?

//get the full location of the assembly with DaoTests in it string fullPath = System.Reflection.Assembly.GetAssembly(typeof(DaoTests)).Location; //get the folder that''s in string theDirectory = Path.GetDirectoryName( fullPath );


¿Qué pasa con esto?

System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);


Aquí hay un puerto VB.NET del código de John Sibly. Visual Basic no distingue entre mayúsculas y minúsculas, por lo que un par de sus nombres de variables chocaron con nombres de tipo.

Public Shared ReadOnly Property AssemblyDirectory() As String Get Dim codeBase As String = Assembly.GetExecutingAssembly().CodeBase Dim uriBuilder As New UriBuilder(codeBase) Dim assemblyPath As String = Uri.UnescapeDataString(uriBuilder.Path) Return Path.GetDirectoryName(assemblyPath) End Get End Property


El directorio actual donde existes.

Environment.CurrentDirectory; // This is the current directory of your application

Si copia el archivo .xml con la compilación, debe encontrarlo.

o

System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly(typeof(SomeObject)); // The location of the Assembly assembly.Location;


En todos estos años, nadie ha mencionado realmente este. Un truco que aprendí del increíble proyecto ApprovalTests . El truco es que utiliza la información de depuración en el ensamblaje para encontrar el directorio original.

Esto no funcionará en el modo LIBERACIÓN, ni con las optimizaciones habilitadas, ni en una máquina diferente de aquella en la que se compiló.

Pero esto le proporcionará rutas que son relativas a la ubicación del archivo de código fuente desde el que lo llama.

public static class PathUtilities { public static string GetAdjacentFile(string relativePath) { return GetDirectoryForCaller(1) + relativePath; } public static string GetDirectoryForCaller() { return GetDirectoryForCaller(1); } public static string GetDirectoryForCaller(int callerStackDepth) { var stackFrame = new StackTrace(true).GetFrame(callerStackDepth + 1); return GetDirectoryForStackFrame(stackFrame); } public static string GetDirectoryForStackFrame(StackFrame stackFrame) { return new FileInfo(stackFrame.GetFileName()).Directory.FullName + Path.DirectorySeparatorChar; } }


Encuentro mi solución adecuada para la recuperación de la ubicación.

var executingAssembly = new FileInfo((Assembly.GetExecutingAssembly().Location)).Directory.FullName;


Es tan simple como esto:

var dir = AppDomain.CurrentDomain.BaseDirectory;


Esto debería funcionar, a menos que el ensamblaje se copie a la sombra :

string path = System.Reflection.Assembly.GetExecutingAssembly().Location


Esto debería funcionar:

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap(); Assembly asm = Assembly.GetCallingAssembly(); String path = Path.GetDirectoryName(new Uri(asm.EscapedCodeBase).LocalPath); string strLog4NetConfigPath = System.IO.Path.Combine(path, "log4net.config");

Estoy usando esto para implementar bibliotecas de archivos DLL junto con algún archivo de configuración (esto es para usar log4net desde dentro del archivo DLL).


Esto es lo que se me ocurrió. Entre proyectos web, pruebas unitarias (nunit y resharper test runner) ; Encontré esto funcionó para mí.

He estado buscando un código para detectar en qué configuración está la compilación, Debug/Release/CustomName . Por desgracia, el #if DEBUG . Así que si alguien puede mejorar eso !

Siéntase libre de editar y mejorar.

Obteniendo carpeta de aplicaciones . Útil para las raíces web, pruebas de unidad para obtener la carpeta de archivos de prueba.

public static string AppPath { get { DirectoryInfo appPath = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory); while (appPath.FullName.Contains(@"/bin/", StringComparison.CurrentCultureIgnoreCase) || appPath.FullName.EndsWith(@"/bin", StringComparison.CurrentCultureIgnoreCase)) { appPath = appPath.Parent; } return appPath.FullName; } }

Obteniendo carpeta bin : Útil para ejecutar ensamblajes usando reflexión. Si los archivos se copian allí debido a las propiedades de construcción.

public static string BinPath { get { string binPath = AppDomain.CurrentDomain.BaseDirectory; if (!binPath.Contains(@"/bin/", StringComparison.CurrentCultureIgnoreCase) && !binPath.EndsWith(@"/bin", StringComparison.CurrentCultureIgnoreCase)) { binPath = Path.Combine(binPath, "bin"); //-- Please improve this if there is a better way //-- Also note that apps like webapps do not have a debug or release folder. So we would just return bin. #if DEBUG if (Directory.Exists(Path.Combine(binPath, "Debug"))) binPath = Path.Combine(binPath, "Debug"); #else if (Directory.Exists(Path.Combine(binPath, "Release"))) binPath = Path.Combine(binPath, "Release"); #endif } return binPath; } }


He definido la siguiente propiedad como la usamos a menudo en pruebas de unidad.

public static string AssemblyDirectory { get { string codeBase = Assembly.GetExecutingAssembly().CodeBase; UriBuilder uri = new UriBuilder(codeBase); string path = Uri.UnescapeDataString(uri.Path); return Path.GetDirectoryName(path); } }

La propiedad Assembly.Location veces te da algunos resultados divertidos cuando usas NUnit (donde los ensamblados se ejecutan desde una carpeta temporal), así que prefiero usar CodeBase que te da la ruta en formato URI, luego UriBuild.UnescapeDataString elimina el File:// en al principio, y GetDirectoryName cambia al formato normal de Windows.


He estado usando Assembly.CodeBase en lugar de Location:

Assembly a; a = Assembly.GetAssembly(typeof(DaoTests)); string s = a.CodeBase.ToUpper(); // file:///c:/path/name.dll Assert.AreEqual(true, s.StartsWith("FILE://"), "CodeBase is " + s); s = s.Substring(7, s.LastIndexOf(''/'') - 7); // 7 = "file://" while (s.StartsWith("/")) { s = s.Substring(1, s.Length - 1); } s = s.Replace("/", "//");

Ha estado funcionando, pero ya no estoy seguro de que sea 100% correcto. La página en http://blogs.msdn.com/suzcook/archive/2003/06/26/assembly-codebase-vs-assembly-location.aspx dice:

"La base de código es una URL del lugar donde se encontró el archivo, mientras que la ubicación es la ruta donde se cargó. Por ejemplo, si el ensamblaje se descargó de Internet, su base de código puede comenzar con" http: // " , pero su ubicación puede comenzar con "C: /". Si el archivo fue copiado en la sombra, la ubicación sería la ruta a la copia del archivo en el directorio de instantáneas. También es bueno saber que la Base de códigos no está garantizada se establecerá para los conjuntos en la GAC. Sin embargo, la ubicación siempre se establecerá para los conjuntos cargados desde el disco " .

Es posible que desee utilizar CodeBase en lugar de la ubicación.


Igual que la respuesta de John, pero con un método de extensión un poco menos detallado.

public static string GetDirectoryPath(this Assembly assembly) { string filePath = new Uri(assembly.CodeBase).LocalPath; return Path.GetDirectoryName(filePath); }

Ahora puedes hacer:

var localDir = Assembly.GetExecutingAssembly().GetDirectoryPath();

o si prefieres:

var localDir = typeof(DaoTests).Assembly.GetDirectoryPath();


La única solución que me funcionó al usar CodeBase y UNC Network compartidos fue:

System.IO.Path.GetDirectoryName(new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath);

También funciona con URI normales también.


Obtendrá un directorio incorrecto si una ruta contiene el símbolo ''#''. Así que uso una modificación de la respuesta de John Sibly que es una combinación de UriBuilder.Path y UriBuilder.Fragment:

public static string AssemblyDirectory { get { string codeBase = Assembly.GetExecutingAssembly().CodeBase; UriBuilder uri = new UriBuilder(codeBase); //modification of the John Sibly answer string path = Uri.UnescapeDataString(uri.Path.Replace("/", "//") + uri.Fragment.Replace("/", "//")); return Path.GetDirectoryName(path); } }


Por lo que puedo decir, la mayoría de las otras respuestas tienen algunos problemas.

La forma correcta de hacer esto para un ensamblado no basado en disco (basado en la web) no basado en GAC es usar la propiedad CodeBase del ensamblado que se ejecuta actualmente.

Esto devuelve una URL ( file:// ). En lugar de perder el tiempo con la manipulación de cadenas o UnescapeDataString , esto se puede convertir con un mínimo LocalPath al aprovechar la propiedad LocalPath de Uri .

var codeBaseUrl = Assembly.GetExecutingAssembly().CodeBase; var filePathToCodeBase = new Uri(codeBaseUrl).LocalPath; var directoryPath = Path.GetDirectoryName(filePathToCodeBase);


Puede obtener la ruta de bin por AppDomain.CurrentDomain.RelativeSearchPath


Qué tal esto ...

string ThisdllDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

Luego simplemente corta lo que no necesitas


Sospecho que el verdadero problema aquí es que su corredor de pruebas está copiando su ensamblaje en una ubicación diferente. En el tiempo de ejecución, no hay forma de saber de dónde se copió el ensamblaje, pero probablemente pueda activar un interruptor para decirle al corredor de prueba que ejecute el ensamblaje desde donde está y no lo copie en un directorio sombra.

Este cambio es probable que sea diferente para cada corredor de prueba, por supuesto.

¿Ha considerado integrar sus datos XML como recursos dentro de su ensamblaje de prueba?


Tengo el mismo comportamiento en la NUnit en el pasado. Por defecto, NUnit copia su ensamblaje en el directorio temporal. Puedes cambiar este comportamiento en la configuración de NUnit :

Tal vez TestDriven.NET y MbUnit GUI tienen la misma configuración.


Todas las respuestas propuestas funcionan cuando el desarrollador puede cambiar el código para incluir el fragmento de código requerido, pero si desea hacerlo sin cambiar ningún código, puede usar Process Explorer.

Enumera todas las dll ejecutadas en el sistema, es posible que deba determinar el ID de proceso de su aplicación en ejecución, pero eso no suele ser demasiado difícil.

He escrito una descripción completa de cómo hacer esto para una dll dentro de II - http://nodogmablog.bryanhogan.net/2016/09/locating-and-checking-an-executing-dll-on-a-running-web-server/


Utilizo esto para obtener la ruta al directorio Bin:

var i = Environment.CurrentDirectory.LastIndexOf(@"/"); var path = Environment.CurrentDirectory.Substring(0,i);

Obtienes este resultado:

"c: / users / ricooley / documents / visual studio 2010 / Projects / Windows_Test_Project / Windows_Test_Project / bin"


en una aplicación de formulario de Windows, simplemente puede usar Application.StartupPath

pero para DLL y aplicaciones de consola, el código es mucho más difícil de recordar ...

string slash = Path.DirectorySeparatorChar.ToString(); string root = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); root += slash; string settingsIni = root + "settings.ini"


AppDomain.CurrentDomain.BaseDirectory

funciona con MbUnit GUI.


string path = Path.GetDirectoryName(typeof(DaoTests).Module.FullyQualifiedName);


var assembly = System.Reflection.Assembly.GetExecutingAssembly(); var assemblyPath = assembly.GetFiles()[0].Name; var assemblyDir = System.IO.Path.GetDirectoryName(assemblyPath);