2008-11-05 19 views
7

Entonces ... solía pensar que cuando accedía a un archivo pero especificaba el nombre sin una ruta (CAISLog.csv en mi caso), .NET esperaría que el archivo residiera en la misma ruta que el .exe en ejecución.¿Cómo funciona la resolución de ruta predeterminada/relativa en .NET?

Esto funciona cuando estoy pasando a través de una solución (C# .NET2. * VS2K5), pero cuando corro la aplicación en modo normal (comenzó con un Websphere MQ gatillo monitorear & ejecuta en segundo plano como un servicio de red) en lugar de acceder al archivo en la ruta donde el .exe se está buscando en C: \ WINDOWS \ system32. Si importa .exe de la tarea de los padres es casi de la misma estructura de carpetas/camino que mi aplicación

recibo un error de coincidencia: "System.UnauthorizedAccessException: acceso a la ruta 'C: \ WINDOWS \ system32 \ CAISLog. csv 'está denegado. "

Mi solución consiste en calificar completamente la ubicación de mi archivo. Sin embargo, lo que quiero entender es "¿Qué es la regla .NET que rige cómo se resuelve una ruta cuando solo se especifica el nombre del archivo durante IO?" Siento que me falta un concepto básico y me está molestando.

editar - No estoy seguro de que sea una regla .NET per se pero Schmuli parece estar explicando el concepto un poco más claro. Definitivamente intentaré las sugerencias de Rob Prouse en el futuro así que +1 en eso también.

Si alguien tiene algunas sugerencias de reformulación que hacen hincapié en que no realmente se preocupan por encontrar la ruta de acceso a mi .exe, simplemente no entendía qué estaba pasando con la resolución de ruta relativa (y aún puedo tiene mi terminología jodida) ...

Respuesta

10

Cuando una aplicación (WinForms) se pone en marcha, el Environment.CurrentDirectory contiene la ruta de la carpeta de la aplicación (es decir, la carpeta que contiene el conjunto de .exe). Usando cualquiera de los cuadros de diálogo de archivos, ej. OpenFileDialog, SaveFileDialog, etc. hará que el directorio actual cambie (si se seleccionó una carpeta diferente).

Al ejecutar un servicio de Windows, su carpeta contenedora es C: \ Windows \ System32, ya que esa es la carpeta del sistema y es el sistema (es decir, el sistema de operación) el que está ejecutando su servicio de Windows.

Tenga en cuenta que al especificar una ruta relativa en la mayoría de los objetos System.IO, recurrirá a utilizar la propiedad Environment.CurrentDirectory.

Como se ha mencionado, existen varias maneras de obtener la ruta del ejecutable del servicio, utilizando Assembly.GetEntryAssembly() o Assembly.GetExecutingAssembly() y luego utilizando ya sea la propiedad Location o la CodeBase propiedad (tenga en cuenta que esta es la ruta del archivo, no directorio, de la ejecutable).

Otra opción es utilizar:

`System.IO.Directory.SetCurrentDirectory(System.AppDomain.CurrentDomain.BaseDirectory);` 

realizar la llamada en el método del Servicio OnStart, aplicándolo a toda la aplicación.

+0

Gracias - Creo que esto ayuda más –

4

Resolución de ruta relativa nunca trabaja en contra de la ruta del archivo ejecutable de inicio. Siempre funciona en contra del directorio actual del proceso, y no se puede esperar que siempre se establezca en el directorio en el que vive el .exe.

Si necesita ese comportamiento, entonces tenga cuidado de encontrar el camino correcto por su cuenta y proporcionar una ruta completa a las operaciones de archivo.

9

Se basa en el directorio de trabajo actual que puede o no ser el mismo donde reside su aplicación, especialmente si se inició desde un programa diferente o un acceso directo con un directorio de trabajo diferente.

En lugar de codificar el camino, obtenga la ruta a su programa y úselo. Puede hacer esto con algo como esto

Assembly ass = Assembly.GetEntryAssembly(); 
string dir = Path.GetDirectoryName(ass.Location); 
string filename = Path.Combine(dir, "CAISLog.csv"); 

Esto supone que el conjunto de entrada es donde se encuentra su archivo. Si no, puede cambiar obteniendo el ensamblado para algo así como;

Assembly ass = Assembly.GetAssembly(typeof(AClassInYourAssembly)); 
+2

Si mal no recuerdo, Assembly.Location devuelve la ruta completa al ensamblado, es decir, incluye el nombre del archivo. Entonces tendría que llamar a Path.GetDirectoryName (ass.Location) para realmente obtener el directorio. Aparte de eso, +1 por la respuesta. – OregonGhost

+0

Gracias, Rob: algo útil, pero creo que la respuesta de Schmuli dio más información sobre el concepto general de lo que me molestaba. +1 –

-2

Puede usar esto para especificar una ruta que resida en la misma ruta que su exe @ ".. \ CAISLog.csv". Tenga en cuenta que los puntos dobles hacen referencia al directorio padre de donde se encuentra su .exe.

RWendi

Cuestiones relacionadas