It's all about absolute and relative paths. As your path is relative, it is "prepended" with your process working directory.
So, when you run your program within your application dirrectory (say C:\MyProgram\
) - path a.abc
is equal to C:\MyProgram\a.abc
. If you run it from different directory (say C:\
) like this: .\MyProgram\my-prog.exe
, then path a.abc
is equal to C:\a.abc
. You can get your current working directory with System.IO.Directory.GetCurrentDirectory()
method to check this by your self.
When you use "Open with" menu - your current directory will be %windir%\system32
and this is "by-design", you shouldn't try to change this.
You can solve your problem by converting relative path to absolute path, like this:
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
}
Another option is to change your working directory somewhere in the beginning of your program:
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
}
However, in this case you should somehow restore your working directory at the end of your program, because this will be frustrating for your users if they will forcibly moved to some path at the end (i would hate such program if you ask me).
There is also a recomendation in some comment to add your app directory to the %PATH%
evironment variable. This will do the trick, but please, don't pollute your %PATH%
if you clearly don't need this. %PATH%
is not limitless - here is a good explanation.
And just a side note. There is no real need to deal with streams and stream readers for reading a file line-by-line. There is a File.ReadAllLines()
method:
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
}
As I said, it will read it line-by-line, so it's ok to read a huge file (it will not load a whole file into your memory, just one single line at a time). If your file is not so big, you could also read it all in one shot into a single string
with File.ReadAllText()
method.