-1

So to summarize I'm making a program that's supposed to look for a txt in the folder of the exe, if it does not find the txt it will create it, when I ran the program the txt wasn't there. This is how I got the directory/path of the exe:

string dir = AppDomain.CurrentDomain.BaseDirectory;

So I tried to write "dir" to the Console, which gives me the directory:

C:\Users\alvin\AppData\Local\Temp.net\GlosFörhör\gbmh2ttz.bkf\glosor.txt

Which is in the windows temp folder. I'm guessing console applications run in the windows temp directory. But what I need is the directory/path for the actual exe file. How can I do this?

Heres the code:

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

namespace GlosFörhör
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] lang1 = { "word1", "word2", "g", "a", "d" };
            string[] lang2 = { "word1", "word2", "g", "a", "d" };

            bool running = true;
            bool firstTime = true;

            while (running)
            {
                if (firstTime)
                {
                    main(lang1, lang2);
                    running = false;
                }
            }

            void main(string[] lang1, string[] lang2)
            {
                Console.WriteLine(getValidTxt());
                Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory);
                Console.ReadLine();

                int[] choiceSeed = getChoiceSeed(lang1);
                lang1 = followSeed(choiceSeed, lang1);
                lang2 = followSeed(choiceSeed, lang2);

                int score = 0;

                for (int m = 0; m < lang1.Length; m++)
                {
                    Console.WriteLine(lang1[m]);
                    string input = Console.ReadLine();
                    if (input.ToLower() == lang2[m].ToLower())
                    {
                        Console.WriteLine("Rätt!");
                        score++;
                    }
                    else
                    {
                        Console.WriteLine("Tyvärr, fel :(");
                    }

                }
                Console.WriteLine();
                Console.WriteLine("Du fick " + score + " rätt av " + lang1.Length + " möjliga.");
                Console.ReadLine();
            }

            int[] getChoiceSeed(string[] input)
            {
                var iL = new List<string>(input);
                var rL = new List<int>();
                var intL = new List<int>();

                for (int t = 0; t < input.Length; t++)
                {
                    intL.Add(t);
                }

                for (int t = 0; t < input.Length; t++)
                {
                    Random rnd = new Random();
                    int tmpIDX = rnd.Next(0, (iL.Count));
                    rL.Add(intL[tmpIDX]);
                    iL.RemoveAt(tmpIDX);
                    intL.RemoveAt(tmpIDX);
                }

                int[] r = rL.ToArray();
                return r;
            }

            string[] followSeed(int[] seed, string[] input)
            {
                var rL = new List<string>();

                foreach (int i in seed)
                {
                    rL.Add(input[i]);
                }

                string[] r = rL.ToArray();
                return r;
            }

            string getValidTxt()
            {
                
                string dir = AppDomain.CurrentDomain.BaseDirectory;
                
                if (File.Exists("glosor.txt"))
                {
                    return dir + "glosor.txt";
                }
                else
                {
                    int txtCnt = 0;
                    var txts = new List<string>();

                    DirectoryInfo di = new DirectoryInfo(dir);
                    foreach (FileInfo file in di.GetFiles())
                    {
                        if (file.ToString().Substring(file.ToString().Length - 4) == ".txt")
                        {
                            txtCnt++;
                            txts.Add(file.ToString());
                        }
                    }

                    if (txtCnt > 0)
                    {
                        return dir + txts[0];
                    }
                    else
                    {
                        File.Create(dir + "glosor.txt");
                        Environment.Exit(0);
                        return dir + "glosor.txt";
                    }
                }
            }
        }
    }
}

The program is supposed to take in two arrays of words (lang1 and lang2) and print them to the console and "exam" the user to write them in another language, this could be useful for example for schoolwork. Anyway, the part where I get the arrays from a txt file is where I'm stuck. The "getValidTxt" method will first check if the file "glosor.txt" is in the directory, if it is it will return the path of the file "glosor.txt" which is done simply by adding the directory and "glosor.txt". If not however, it will check if any other files that end with ".txt" If there are, it will add them to a list and return the first item, along with the directory. If not it will add "glosor.txt", and close the program so that the user can input the words into the txt.

The "getChoiceSeed" and "followSeed" are just for randomizing the order of the words.

Mallard
  • 1
  • 2
  • You check for a file "glosor.txt", and then return dir + "glosor.txt", so that's one mistake. – Bent Tranberg Jan 26 '22 at 20:01
  • When combining paths, use System.IO.Paths.Combine. If you just +, then you risk that backslashes are not treated correctly. And you can't know whether or not a backslashes is there every time you call, so it may succeed one time and fail another time. – Bent Tranberg Jan 26 '22 at 20:04
  • 1
    Your question lacks detail and focus. You give too much information, but not enough about the actual problem you have. It's a lot to ask that we read or run through your program to understand what the problem is. Read [how to ask](https://stackoverflow.com/help/how-to-ask) – Bent Tranberg Jan 26 '22 at 20:08
  • "I'm guessing console applications run in the windows temp directory." No, it depends on many factors where it runs, but I don't think that's normal. – Bent Tranberg Jan 26 '22 at 20:14
  • No matter which method I use to get the path, it always returns some folder in the temp bin. The only way to get around that problem is to compile the program normally, then it runs just fine and creates the file. However, I would like to be able to compile the program into a singe exe, to do that I use the publish menu in visual studio code, I change deployment mode to "self-contained", and under file publish options I check "produce single file". That gives me a exe and a pdb which isnt needed. So the real question is: How can I compile my program so that it is one exe, and still returns – Mallard Jan 27 '22 at 18:52
  • the correct path? – Mallard Jan 27 '22 at 18:52
  • If you have tried the various methods that Nicholas has listed, and they all return a folder in the "temp bin", then isn't the executable file also in that folder when you run in Visual Studio? – Bent Tranberg Jan 27 '22 at 21:34

1 Answers1

0

Assuming your executable is a standard application (e.g., a console app) or similar, you can get the path of the current executable in a couple of different ways:

  • System.Reflection.Assembly.GetEntryAssembly().Location
    Note that this may be incorrect if the executing process is not a normal, stand-alone executable.

  • Assembly.GetExecutingAssembly().Location
    This provides the path to the currently executing assembly. It may be incorrect if your app has been GAC'd or otherwise lives separately from the rest of your application.

  • System.Environment.ProcessPath
    Note that this may be incorrect if the executing process is not a normal, stand-alone executable.

  • System.Environment.GetCommandLineArgs()[0]
    Note though, that this may or may not have path information.

See also my answers at

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135