2008-10-31 7 views
16

Para mis aplicaciones, almaceno algunos archivos de configuración en xml junto con el ensamblado (exe) y otros archivos temporales para fines de proceso.Cuál es la mejor manera de obtener el directorio desde el que se está ejecutando un ensamblaje

Encontré algunas peculiaridades con ".\\" y Application.StartupPath.

He estado usando

String configPath = ".\\config.xml"; 

Funciona bien hasta que se llama OpenFIleDialog abrir algunos archivos en otras carpetas, la afirmación anterior fracasaron. Aparentemente ". \" Se refiere a "CurrentDirectory", que cambia cada vez que navegamos a otra carpeta.

En algún momento, yo estaba usando

String configPath = Path.Combine(Application.StartupPath + "config.xml"); 

En algún momento, cuando necesito para ejecutar este montaje de otra carpeta utilizando Process.Start(), las cosas comienzan a desmoronarse. Aparentemente, el directorio de trabajo no está configurado correctamente, y Application.StartupPath se está refiriendo al directorio de trabajo en lugar del directorio en el que se está ejecutando el ensamblado, como he supuesto. Así que tengo que recurrir a ProcessInfo para configurar el directorio de trabajo en el directorio del ensamblado. También tuve un problema con esto cuando escribía VSTO.

Entonces, mi pregunta es, ¿cuál es la mejor manera, la más simple y segura de obtener el directorio actual que está ejecutando el ensamblado, sin esos caprichos (o malentendidos) que acabo de mencionar?

EDIT: Me refería a obtener el directorio de la cual el conjunto residen

EDIT: De acuerdo con MSDN en AppDomain.BaseDirectory, parece que puede haber cambios durante el tiempo de ejecución, que es lo que no quiero (sólo para aclarar , no es que no quiera permitir el cambio de BaseDirectory, sino más bien, cuando lo recupere sin saber con certeza si ha sido cambiado)

EDIT: he notado que una pregunta relacionada fue publicada mucho antes. What would cause the current directory of an executing app to change?

Gracias chicos por la respuesta.

Respuesta

42
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)) 
+0

¿este método involucra la reflexión? como en el impacto en el rendimiento? – faulty

+0

No estoy seguro de que haya una correlación 1: 1 entre "reflexión" e "impacto en el rendimiento"; está en el espacio de nombres de Reflexión, pero no se refleja en el conjunto, está utilizando los metadatos que ya conoce. – GalacticCowboy

+12

Sí ... Haga solo UNA LLAMADA como esta para ver cómo absorbe todos sus ciclos de CPU y convierte su Xeon Octa-core en un HP12c. Porque cualquiera sabe que Reflection es el engendro de Satanás y representa todo lo que es verdad en el mundo (créditos a Scott Hanselman por el nombre :)) –

9

¿Desea el directorio de trabajo actual o el directorio que contiene el conjunto? No está del todo claro.

Hay Environment.CurrentDirectory si quiere el directorio de trabajo, o Path.GetDirectoryName(typeof(Foo).Assembly.ManifestModule.FullyQualifiedName) para encontrar la ubicación de un conjunto (o al menos su módulo de manifiesto, que será lo mismo en casi todos los casos).

+0

cuidado con 'Environment.CurrentDirectory' si utilizarlo desde dentro de las aplicaciones que los diálogos de archivo abierto (Winforms + WPF), ya que sólo navegar en un directorio diferente cambiará' Environment.CurrentDirectory' –

5

También hay,

System.Reflection.Assembly.GetExecutingAssembly().CodeBase 
+0

@tafa, se me adelantó eso. :) @Jon, también intente System.Reflection.Assembly.GetExecutingAssembly(). Ubicación – Kon

+0

Ambas respuestas no son las que realmente se solicitan. Robinkor es una respuesta más completa. – tafa

1

¿Qué tal

string currentAssemblyFile = System.Reflection.Assembly.GetExecutingAssembly().Location; 

y luego comprenderlo a partir de ahí ...

2

me gustaría probar algo como esto en la siguiente link:

string path; 
path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase); 
MessageBox.Show(path); 
4

Un poco más corto:

AppDomain.Current.BaseDirectory 
+1

Debe ser AppDomain.CurrentDomain .BaseDirectory en lugar de AppDomain.Current.BaseDirectory. –

11

Pruebe la aplicación a continuación. La propiedad CodeBase es la forma más confiable de obtener la ubicación, y luego el resto del código la convierte en formato estándar de Windows (en lugar de un URI).

static public string AssemblyLoadDirectory 
{ 
    get 
    { 
     string codeBase = Assembly.GetCallingAssembly().CodeBase; 
     UriBuilder uri = new UriBuilder(codeBase); 
     string path = Uri.UnescapeDataString(uri.Path); 
     return Path.GetDirectoryName(path); 
    } 
} 
+0

Su solución no funciona si la ruta tiene marcas de almohadilla. – dcp

Cuestiones relacionadas