Проблема с относительным путем с .Net Windows Service ..?

У меня есть служба Windows, которая пытается получить доступ к XML-файлу из каталога приложения.

Каталог установленной службы Windows: C: \ Services \ MyService \ MyService.exe
Путь к XML-файлу: C: \ Services \ MyService \ MyService.xml

Я пытаюсь получить доступ к файлу, используя следующий код.

using (FileStream stream = new FileStream("MyService.xml", FileMode.Open, FileAccess.Read))
  {
         //Read file           
  }

Я получаю следующую ошибку.

«Не удается найти файл: C: \ WINDOWS \ system32 \ MyService.xml»

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


person Amitabh    schedule 26.04.2010    source источник


Ответы (3)


Для этого есть элегантное решение по следующей ссылке.

http://haacked.com/archive/2004/06/29/current-directory-for-windows-service-is-not-what-you-expect.aspx/

Поскольку моя служба работает как консоль / служба, я только что позвонил

Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory) 

перед запуском в качестве службы.

static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
                RunAsService();
            }
            else
            {
                RunAsConsole();
            }
        }
person Amitabh    schedule 26.04.2010
comment
также спас мою жизнь - person Nam Nguyen; 24.12.2018
comment
Вы можете добавить еще одну жизнь в список - person ceds; 04.01.2019

Вам нужно найти путь к сборке вашего сервиса, например:

static readonly string assemblyPath = 
    Path.GetDirectoryName(typeof(MyClass).Assembly.Location);

using (FileStream stream = File.OpenRead(Path.Combine(assemblyPath, "MyService.xml"))
person SLaks    schedule 26.04.2010
comment
В этом случае надежнее использовать Location, а не _2 _... см. Документацию MSDN для получения информации. - person Noldorin; 26.04.2010
comment
Другая проблема заключается в том, что вы используете typeof(MyClass).Assembly для получения основной сборки программы. Assembly.GetEntryAssembly() снова надежнее. - person Noldorin; 26.04.2010
comment
@ Noldorin # 2: Напротив. Его код должен работать независимо от того, кто вызвал его сборку. - person SLaks; 26.04.2010
comment
Я думаю, вы упустили суть. Вы не знаете, где будет определен этот код. Семантически нас интересует не то, где определен класс, а то, какая сборка ОС сначала загрузила для программы. - person Noldorin; 26.04.2010
comment
Я так не думаю. Его код находится в сборке, которая была установлена ​​в определенное место. Он хочет заглянуть в это место, независимо от того, как выполнялась его сборка. - person SLaks; 26.04.2010

Когда запускается служба Windows, текущий каталог - это системный каталог, как вы действительно, кажется, заметили. Это текущий каталог, который используется для преобразования относительных путей в абсолютные пути, а не каталог вашего приложения (службы). (Проверьте переменную Environment.CurrentDirectory, если хотите подтвердить это.)

Здесь может пригодиться следующий вспомогательный метод:

public static string GetAppRelativePath(string path)
{
    return Path.Combine(Path.GetDirectoryName(
        Assembly.GetEntryAssembly().Location), path);
}

Который затем можно использовать как:

using (FileStream stream = new FileStream(Utilities.GetAppRelativePath(
    "MyService.xml"), FileMode.Open, FileAccess.Read))
{
    // Read file
}

Затем путь будет преобразован в C:\Services\MyService\MyService.xml, как вы хотите.

person Noldorin    schedule 26.04.2010
comment
Разве путь не разрешится в C: \ Services \ MyService \ MyService.xml, что и требуется? Думаю, это просто опечатка. - person Waleed Al-Balooshi; 26.04.2010
comment
@ Валид: Извини, ты прав. Он указывает на правильный путь, я просто написал неправильный «правильный путь». ;) - person Noldorin; 26.04.2010
comment
GetAbsolutePath (string relativePath) может быть лучшим именем метода. - person Zorayr; 09.08.2013
comment
Этого я и хотел. Спасибо! - person ilter; 22.03.2019