¿Cómo obtengo la ruta del ensamblado en el que se encuentra el código?

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

Básicamente, mi unidad de prueba necesita leer algunos archivos de prueba xml que se encuentran en relación con el dll. Quiero que la ruta siempre se resuelva correctamente, independientemente de si la dll de prueba se ejecuta desde TestDriven.NET, la interfaz gráfica de usuario de MbUnit u otra cosa.

Editar : La gente parece estar entendiendo mal lo que estoy preguntando.

Mi biblioteca de prueba está ubicada en say

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

y me gustaría obtener este camino:

C: \ projects \ myapplication \ daotests \ bin \ Debug \

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

  • Environment.CurrentDirectory da c: \ Program Files \ MbUnit

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

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

He definido la siguiente propiedad ya que la usamos a menudo en pruebas unitarias.

 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 le da algunos resultados divertidos cuando usa NUnit (donde los ensamblados se ejecutan desde una carpeta temporal), entonces prefiero usar CodeBase que le da la ruta en formato URI, luego UriBuild.UnescapeDataString elimina el File:// en al principio, y GetDirectoryName cambia al formato de Windows normal.

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

Es tan simple como esto:

 var dir = AppDomain.CurrentDomain.BaseDirectory; 

Lo mismo que la respuesta de John, pero 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 lo prefiere:

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

La única solución que funcionó para mí al usar CodeBase y las acciones de UNC Network fue:

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

También funciona con URI normales también.

Esto debería funcionar, a menos que el ensamblaje esté copiado en la sombra :

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

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

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

¿Ha considerado incorporar sus datos XML como recursos dentro de su conjunto de prueba?

¿Qué tal esto?

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

funciona con la GUI de MbUnit.

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

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 colisionaron con nombres de tipos.

 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 

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 funcionado, 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:

“CodeBase es una URL al lugar donde se encontró el archivo, mientras que la ubicación es la ruta donde se cargó realmente. Por ejemplo, si el ensamblado se descargó de Internet, su CodeBase puede comenzar con” http: // “. , pero su ubicación puede comenzar con “C: \”. Si el archivo fue copiado de 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 CodeBase no está garantizado. para establecerse para ensamblajes en el GAC. Sin embargo, siempre se establecerá la ubicación para los ensamblajes cargados desde el disco.

Es posible que desee utilizar CodeBase en lugar de Location.

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

Esto no funcionará en el modo RELEASE, ni con optimizaciones habilitadas, ni en una máquina diferente a la que se compiló.

Pero esto te dará caminos que son relativos a la ubicación del archivo de código fuente del que lo llamas

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

El directorio actual donde existes

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

Si copia el archivo .xml con comstackción, debería encontrarlo.

o

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

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

La forma correcta de hacer esto para un ensamblado sin GAC basado en disco (en lugar de basado en web) es usar la propiedad CodeBase la ensambladura que se está ejecutando 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 alboroto mínimo al aprovechar la propiedad LocalPath de Uri .

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

Qué tal esto …

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

Entonces simplemente corte lo que no necesitas

Puede obtener la ruta bin por AppDomain.CurrentDomain.RelativeSearchPath

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

Enumerará todos los dlls ejecutables en el sistema, es posible que necesite determinar el id. De proceso de su aplicación en ejecución, pero eso generalmente no es demasiado difícil.

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

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

pero para las DLL y las 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" 
 string path = Path.GetDirectoryName(typeof(DaoTests).Module.FullyQualifiedName); 

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

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

Siéntase libre de editar y mejorar.

Obteniendo la carpeta de aplicaciones . Útil para raíces web, unittests 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; } } 

Obtención de la carpeta bin : Útil para ejecutar ensamblajes usando reflexión. Si los archivos se copian allí debido a las propiedades de comstackció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; } } 

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 el archivo DLL).

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

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

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

enter image description here

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

Lo uso para obtener la ruta al Directorio de 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”

¿Aplicación web?

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