Что может привести к изменению текущего каталога исполняемого приложения? - PullRequest
2 голосов
/ 01 октября 2008

У меня есть приложение на C #, содержащее следующий код:

string file = "relativePath.txt";

//Time elapses...

string contents = File.ReadAllText(file);

Это работает нормально, большую часть времени. Файл читается относительно каталога, из которого было запущено приложение. Однако при тестировании было обнаружено, что если оставить его в покое на 5 часов, приложение выдаст FileNotFoundException, сообщив, что «C: \ Documents and Settings \ Adminstrator \lativePath.txt» не может быть найден. Если действие, которое читает файл, запускается сразу же, файл читается из правильного местоположения, которое мы назовем «C: \ foo \lativePath.txt»

Что дает? И какое самое лучшее решение? Разрешение файла против Assembly.GetEntryAssembly().Location?

Ответы [ 6 ]

7 голосов
/ 01 октября 2008

Одним из жутких мест, которые могут изменить ваш путь, является OpenFileDialog. Когда пользователь перемещается между папками, он меняет каталог приложения на тот, который просматривается в данный момент. Если пользователь закрывает диалоговое окно в другом каталоге, вы застрянете в этом каталоге.

У него есть свойство с именем RestoreDirectory , которое заставляет диалоговое окно сбрасывать путь. Но я считаю, что по умолчанию "ложь".

5 голосов
/ 01 октября 2008

Если файл всегда находится в пути относительно исполняемой сборки, тогда да, используйте Assembly.Location. Я в основном использую Assembly.GetExecutingAssembly, если применимо, хотя вместо Assembly.GetEntryAssembly. Это означает, что если вы обращаетесь к файлу из DLL, путь будет относительно пути DLL.

2 голосов
/ 01 октября 2008

Я думаю, что урок должен быть не полагаться на относительные пути, они подвержены ошибкам. Текущий каталог может быть изменен любым количеством вещей в вашем рабочем процессе, таких как файловые диалоги (хотя есть свойство, которое не позволяет им изменять его), так что вы никогда не сможете действительно гарантировать, куда относительный путь всегда приведет, если вы не используете относительный путь для генерации фиксированного пути из известного пути, такого как Application.StartupPath (хотя будьте осторожны при запуске из Visual Studio) или другого известного пути.

Использование относительных путей затруднит поддержание вашего кода, поскольку изменение совершенно не связанной части вашего проекта может привести к сбою другой части.

1 голос
/ 01 октября 2008

если вы делаете что-то вроде

> cd c: \ folder 1

c: \ folder 1> ../folder 2 / theApplication.exe

Текущий рабочий каталог приложения - c: \ folder 1.

Вот пример программы

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CWD {
    class Program {
        static void Main (string[] args) {
            Console.WriteLine(Application.StartupPath);
        }
    }
}

Создайте это в visualstudio, затем откройте командную строку в каталоге debug / bin и выполните

bin / debug> CWD.exe

затем сделайте

bin / debug> cd ../../ > bin / debug / CWD.exe

вы увидите разницу в пути запуска.

По отношению к первоначальному вопросу ... «если оставить в покое около 5 часов, приложение выдаст исключение FileNotFoundException»

После запуска приложения эта ошибка может быть вызвана только перемещением или удалением этого файла из ожидаемого места.

Greg

1 голос
/ 01 октября 2008

В System.Environment у вас есть перечисление SpecialFolder , которое поможет вам получить стандартные относительные пути.

Таким образом, по крайней мере, путь получается изнутри и возвращается вам, так что, надеюсь, если система каким-то образом изменит путь, код просто справится с этим.

0 голосов
/ 01 октября 2008

Если вы используете openfiledialog, а свойство запоминания пути (не уверенное в точном названии) имеет значение true, то, я думаю, это изменит ваш текущий каталог.

...