Это все о абсолютных и относительных путях . Поскольку ваш путь относительный, он «предварен» вашим рабочим каталогом .
Итак, когда вы запускаете свою программу в директории приложения (скажем, C:\MyProgram\
) - путь a.abc
равно C:\MyProgram\a.abc
. Если вы запустите его из другого каталога (скажем, C:\
), например: .\MyProgram\my-prog.exe
, то путь a.abc
будет равен C:\a.abc
. Вы можете получить текущий рабочий каталог с помощью System.IO.Directory.GetCurrentDirectory()
метода , чтобы проверить это самостоятельно.
Когда вы используете "Открыть с помощью" меню - ваш текущий каталог будет быть %windir%\system32
и это "by-design" , вы не должны пытаться изменить это.
Вы можете решить свою проблему, преобразовав относительный путь в абсолютный путь, например:
using System.Reflection;
using System.IO;
var appLocation = Assembly.GetEntryAssembly().Location;
var appPath = Path.GetDirectoryName(appLocation);
var reqdFilePath = Path.Combine(appPath, @Properties.Resources.reqdFileName);
using (StreamReader sr = File.OpenText(reqdFilePath))
// read lines and use it here
}
Другой вариант - изменить рабочий каталог где-то в начале вашей программы:
using System.Reflection;
var appLocation = Assembly.GetEntryAssembly().Location;
var appPath = Path.GetDirectoryName(appLocation);
Directory.SetCurrentDirectory(appPath);
// we are in your app directory now for sure
// ... Later in your code ...
using (StreamReader sr = File.OpenText(@Properties.Resources.reqdFileName))
// read lines and use it here
}
Однако в этом случае вам как-то нужно restore ваш рабочий каталог в конце вашей программы, потому что это будет разочаровывать ваших пользователей, если они будут принудительно перемещаться по какому-то пути в конце (я бы не хотел такую программу, если вы спросите меня).
Там В некоторых комментариях также рекомендуется добавлять каталог приложения в переменную %PATH%
evironment. Это поможет, но , пожалуйста , не загрязняйте ваш %PATH%
, если вам это явно не нужно. %PATH%
не безграничен - здесь - хорошее объяснение.
И просто примечание. Нет реальной необходимости иметь дело с потоками и программами чтения потоков для чтения файла построчно. Существует File.ReadAllLines()
метод :
using System.Reflection;
using System.IO;
var appLocation = Assembly.GetEntryAssembly().Location;
var appPath = Path.GetDirectoryName(appLocation);
var reqdFilePath = Path.Combine(appPath, @Properties.Resources.reqdFileName);
foreach (var line in File.ReadAllLines(reqdFilePath))
{
// use your line here
}
Как я уже сказал, он будет читать его построчно , так что нормально читать огромное файл (он не будет загружать весь файл в вашу память, только одну строку за раз). Если ваш файл не такой большой, вы также можете прочитать его за один снимок за один string
с File.ReadAllText()
методом .