У меня есть сервис окон, который пытается получить доступ к XML-файлу от Каталога приложения.
Каталог Windows Service Installed: 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"
Моя услуга работает с локальной системной учетной записью, и я не хочу использовать полный путь.
Есть элегантное решение для этого по следующей ссылке.
Поскольку мой сервис работает и как консоль, и как сервис, я просто вызываю
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory)
перед запуском его как сервиса. Например,
static void Main(string[] args)
{
if (args.Length == 0)
{
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
RunAsService();
}
else
{
RunAsConsole();
}
}
Вам нужно найти путь к сборке вашей службы, например:
static readonly string assemblyPath =
Path.GetDirectoryName(typeof(MyClass).Assembly.Location);
using (FileStream stream = File.OpenRead(Path.Combine(assemblyPath, "MyService.xml"))
Когда запускается служба 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
, как хотите.