.net - net - Encontrar la ruta de mi ejecutable principal utilizando Assembly vs AppDomain
get application directory c# (5)
Soy un usuario de .NET y mi objetivo es tan simple como encontrar la ruta absoluta del directorio de mi ensamblaje principal de ejecución (el archivo EXE).
Tengo varios candidatos:
Assembly.GetExecutingAssembly().CodeBase
-
Assembly.GetExecutingAssembly().Location
-
AppDomain.CurrentDomain.BaseDirectory
Si debo juzgar por la documentación de .NET, me CodeBase
por CodeBase
. ¿Alguien puede arrojar luz sobre los tres términos un poco más específicos que la documentación de .NET? ¿Un ejemplo para demostrar la diferencia quizás?
De: http://msdn.microsoft.com/en-us/library/system.reflection.assembly.codebase.aspx
Assembly.CodeBase
Para obtener la ruta absoluta al archivo cargado que contiene el manifiesto, use la propiedad
Assembly.Location
lugar.Si el ensamblaje se cargó como una matriz de bytes, utilizando una sobrecarga del método de carga que toma una matriz de bytes, esta propiedad devuelve la ubicación de la persona que llama al método, no la ubicación del ensamblaje cargado.
Para AppDomain.CurrentDomain.BaseDirectory
, honestamente no tengo idea acerca de las diferencias desde un punto de vista práctico.
Desafortunadamente, todos los métodos anteriores pueden fallar si utiliza una virtualización como XenoCode postbuild. He probado muchos métodos y he encontrado otra solución here . He encontrado que sólo el
System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe"
Devuelve el nombre de archivo correcto del ejecutable. Así que combinando el nombre del archivo con la ruta desde Assembly.GetEntryAssembly().Location
obtendrá la ruta correcta del ejecutable.
No estoy seguro acerca de AppDomain.CurrentDomain.BaseDirectory
, pero la diferencia entre Assembly.GetExecutingAssembly().CodeBase
y Assembly.GetExecutingAssembly().Location
se explicó en esta publicación del blog .
La base de código es una URL del lugar donde se encontró el archivo, mientras que la ubicación es la ruta desde donde se cargó. Por ejemplo, si el ensamblaje se descargó de Internet, su CodeBase 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 copia de sombra.
También es bueno saber que no se garantiza que la Base de códigos esté configurada para los ensamblajes en el GAC. Sin embargo, la ubicación siempre se establecerá para los ensamblados cargados desde el disco.
Así que parece que su mejor apuesta es Location
si necesita el directorio real desde el que se ejecutó el archivo.
Utilice System.Linq
string MainExecutablePath= (System.Diagnostics.Process.GetProcesses().First(P =>P.MainWindowTitle == "MainExecutable''sWindowName")).MainModule.FileName.ToString();
Yo usaría GetEntryAssembly()
lugar de GetExecutingAssembly()
.
Para ver por qué, haz esto:
- Crear un nuevo proyecto de consola
- Agregue un proyecto de biblioteca de clases (
ClassLibrary1
) a la solución y haga referencia a él desde el Proyecto de la Consola.
Ponga esto en ClassLibrary1
:
namespace ClassLibrary1
{
using System;
using System.IO;
using System.Reflection;
public class Class1
{
public void GetInfo(int n)
{
Assembly asm = Assembly.GetEntryAssembly();
Console.WriteLine("[GetEntryAssembly {0}] Location:{1}", n, Path.GetDirectoryName(asm.Location));
asm = Assembly.GetExecutingAssembly();
Console.WriteLine("[GetExecutingAssembly() {0}] Location:{1}", n, Path.GetDirectoryName(asm.Location));
}
}
}
Pon esto en Program.cs
la consola:
namespace ConsoleApplication4
{
using System;
using System.IO;
using System.Reflection;
using ClassLibrary1;
class Program
{
static void Main(string[] args)
{
Assembly asm = Assembly.GetEntryAssembly();
Console.WriteLine("[GetEntryAssembly() 1] Location:{0}", Path.GetDirectoryName(asm.Location));
asm = Assembly.GetExecutingAssembly();
Console.WriteLine("[GetExecutingAssembly() 1] Location:{0}", Path.GetDirectoryName(asm.Location));
Class1 obj1 = new Class1();
obj1.GetInfo(2);
asm = Assembly.LoadFile(@"C:/temp/ClassLibrary1.dll");
Type t = asm.GetType("ClassLibrary1.Class1");
object obj2 = asm.CreateInstance("ClassLibrary1.Class1");
t.GetMethod("GetInfo").Invoke(obj2, new object[] { 3 });
Console.ReadKey();
}
}
}
Genere la solución, copie ClassLibrary1.dll
a c:/temp
y ejecute.
Como verá, GetExecutingAssembly()
puede engañarlo en ciertas condiciones.
Una última nota, si su aplicación es de Windows Forms, solo puede usar Application.ExecutablePath
.