0

I am trying to make a simple c# program which opens a file in dotnet core 5 using visual studio, however, it transpires that it is looking for the file relative to where the .exe is stored, not my source files. Is there any way I can change this? So that the file can be stored with my source files?

I have tried using Directory.GetCurrentDirectory(), however, this takes me to .exe file, and I need it to open using a relative path rather than the absolute one.

The code is copied and pasted from the Microsoft C# docs here (In the image I have a './' before the filename, I have tried without, it was just something I tried to get it to work.

Code:

using System;
using System.IO;

namespace Test_File_Opening
{
    class Program
    {
        static void Main(string[] args)
        {
            String line;
            try
            {
                //Pass the file path and file name to the StreamReader constructor
                StreamReader sr = new StreamReader("Sample.txt");
                //Read the first line of text
                line = sr.ReadLine();
                //Continue to read until you reach end of file
                while (line != null)
                {
                    //write the lie to console window
                    Console.WriteLine(line);
                    //Read the next line
                    line = sr.ReadLine();
                }
                //close the file
                sr.Close();
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: " + e.Message);
            }
            finally
            {
                Console.WriteLine("Executing finally block.");
            }
        }
    }
}

Exception: Could not find file 'C:\Users\callu\source\repos\Test_File_Opening\Test_File_Opening\bin\Debug\net5.0\Sample.txt'.
Executing finally block.
malik masis
  • 487
  • 1
  • 6
  • 15
Callum
  • 31
  • 5
  • Use the full path to the desired file, instead of a relative path from the executable? – David Aug 25 '21 at 21:23
  • Sorry, I didn't mention this, I need it to be a relative path as it needs to be able to run on another machine. – Callum Aug 25 '21 at 21:25
  • You can also copy files on build to the output folder automatically. See this somewhat unrelated question but the image applies: https://stackoverflow.com/a/26650101/5948452 – naslund Aug 25 '21 at 21:26
  • 1
    Please provide code as text, not as pictures of text, as mentioned on [ask]. – Heretic Monkey Aug 25 '21 at 21:30
  • Current Directory always points to the location of exe. You also mentioned that you want to run it on another machine. So, please specify the path of your file relative to the location of your exe. What you are trying to achieve is access the file relative to your source code location without letting your exe know the location of your source code. You can feed the source folder location to your application and then ask your exe to access relative to it. – Prasad Bhokare Aug 25 '21 at 21:37
  • Do you have control/knowledge about, where the *Sample.txt* will be located on the other machine(s)? Do you deploy it with your exe? If not, then I'd say, you will need some FileDialog to grab the file... if yes, then you can hardcode the relaltive path from your exe, like System.IO.Path.GetFullPath (@"..\..\Myfolder\Sample.txt") - check System.IO.Path for more options – dba Aug 26 '21 at 06:18

1 Answers1

0

The running executable has no knowledge of or connection to the original source code files. They may be moved or deleted entirely for all it knows.

Use an absolute path for your file:

var sr = new StreamReader(@"C:\Some\Path\To\Your\File.txt");

I need it to open using a relative path rather than the absolute one.

No you don't. Because there is no universal relative path between a compiled executable and the source code from which it was compiled.

But a comment on the question offers an alternative:

it needs to be able to run on another machine

That's what config files are for... environment-specific settings. (Alternatively, if your plan all along was to distribute the source code for your users to compile and run themselves then they could simply edit it to their file location anyway.)

If you're using the older App.config style settings, add an App.config to your application and put the file path in the appSettings:

<appSettings>
  <add key="FilePath" value="C:\Some\Path\To\Your\File.txt"/>  
</appSettings>

Then use that setting in the code:

var sr = new StreamReader(System.Configuration.ConfigurationManager.AppSettings["FilePath"]);

Or, if you're using something newer like appsettings.json then there is documentation for that as well. But the principal is still the same.

You could even roll your own way of maintaining application configuration. Hell, you could even skip a config file entirely and provide the file name as a command line argument when running the application. The point is that any given environment would need a way to tell the application where the file is.

David
  • 208,112
  • 36
  • 198
  • 279