Environment.CurrentDirectory дает неожиданные результаты при запуске установленного приложения

Фон:

Я построил установщик для своего приложения, и все мои файлы dll и содержимого правильно копируются в каталог C:\Program Files\MyCompany\MyApp. Когда я запускаю свое приложение из Visual Studio, все отлично работает. Однако, когда я запускаю установленную версию своего приложения, я получаю DirectoryNotFoundException. Проблема, похоже, связана с Environment.CurrentDirectory.

Я ожидал, что Environment.CurrentDirectory будет...

"C:\\Program Files\\MyCompany\\MyApp"

... но это было на самом деле...

"C:\\Documents and Settings\\DanThMan"

Что здесь происходит? Как это решить?

Спасибо.

EDIT:

Хорошо, хм. Эта проблема возникает только при запуске ярлыка "Пуск". Если я запускаю MyApp.exe напрямую, все в порядке.

ИЗМЕНИТЬ 2:

Я думаю, что я дошел до этого момента. В моем установщике (который является Visual Studio SetupProject) ярлык меню "Пуск" имеет свойство WorkingFolder, которое "Указывает папку, в которой будет установлено целевое приложение для ярлыка". Я случайно установил WorkingFolder в "MyCompany". Это должна быть "Папка приложений". Теперь, когда я его правильно установил, Environment.CurrentDirectory снова работает как ожидалось. Спасибо за вашу помощь.

ИЗМЕНИТЬ 3:

Однако, прочитав приведенные ниже предупреждения, я решил пойти со следующим в качестве замены для Environment.CurrentDirectory:

System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);

Ответы

Ответ 1

Если вы хотите получить путь к каталогу, в котором выполняется ваш исполняемый файл, вы не должны полагаться на среду Environment.CurrentDirectory, поскольку его можно изменить несколькими способами (параметры shotrtcut и т.д.). Попробуйте использовать один из следующих вариантов:

System.IO.Path.GetDirectoryName(Application.ExecutablePath);

или

System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);

Ответ 2

Используйте Application.StartupPath вместо Environment.CurrentDirectory.
У меня была аналогичная проблема, когда CurrentDirectory менялся непреднамеренно чем-то вроде OpenFileDialog, даже если я даже не осознавал этого.
В вашем случае это звучит так, как будто процесс, с которого вы запускаете форму заявки, меняет CurrentDirectory без ведома.

Ответ 3

Поскольку вы сказали, что ваше приложение использует WPF, вы можете использовать следующий код вместо Application.StartupPath:

String appPath = System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);

Ответ 4

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

В вашем случае стартовым приложением является оболочка (explorer.exe) в обоих случаях. Он определяет рабочий каталог при запуске программы, в зависимости от контекста запуска. Вы видели два разных случая (двойной щелчок по файлу в проводнике и запуск из меню "Пуск" ); вы также обнаружили, что Microsoft рассматривает наиболее разумные значения для текущего каталога в любом случае: домашний каталог пользователя и каталог, который отображается в проводнике (соответственно).

Ответ 5

В файле Environment.CurrentDirectory содержится текущий каталог, который теперь является текущим каталогом. Значение зависит от многих факторов. Любое приложение может изменить значение. Это значение не относится только к вашему приложению.

Если вы хотите получить начальный каталог, используйте Application.StartupPath.