0

I have winforms c# project and in that I have two .txt files i.e., credentials.txt and RetailButton_Exception.txt. Now I have given path to D: drive at development side. Now what if I install my application in different pc which does not have D: ?

I have given the code for saving these files as follow:-

 private void btnLogin_Click(object sender, EventArgs e)
        {
            try
            {

                string Log_API = "http://api.retailbutton.co/WS/Service.php?Service=employeeLogin";
                if (LoginUser(Log_API))
                {
                    logIn_Status = "true";
                    GlolbalUtil.authenticate = "true";
                    GlolbalUtil.LogIn_Status = logIn_Status;
                    this.Hide();

                    //string credentialPath = @"D:\credentials.txt";
                    String test = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                    if (File.Exists(test + "credentials.txt"))
                    {
                        using (StreamWriter writer = new StreamWriter(test, true))
                        {
                            //writer.WriteLine("UserName :" + txtUsername.Text + Environment.NewLine + "Password :" + txtPassword.Text);
                            writer.WriteLine(txtUsername.Text);
                            writer.WriteLine(txtPassword.Text);
                        }

                        frmDash frmDash = new frmDash();
                        frmDash.Owner = this;
                        frmDash.Show();
                        txtUsername.Text = "";
                        txtPassword.Text = "";
                    }
                    else
                    {
                        using(FileStream fs = File.Create(test))
                        {
                            #region
                            using (StreamWriter writer = new StreamWriter(test, true))
                            {
                                //writer.WriteLine("UserName :" + txtUsername.Text + Environment.NewLine + "Password :" + txtPassword.Text);
                                writer.WriteLine(txtUsername.Text);
                                writer.WriteLine(txtPassword.Text);
                            }

                            frmDash frmDash = new frmDash();
                            frmDash.Owner = this;
                            frmDash.Show();
                            txtUsername.Text = "";
                            txtPassword.Text = "";
                            #endregion
                        }
                        #region
                        //using (StreamWriter writer = new StreamWriter(credentialPath, true))
                        //{
                        //    //writer.WriteLine("UserName :" + txtUsername.Text + Environment.NewLine + "Password :" + txtPassword.Text);
                        //    writer.WriteLine(txtUsername.Text);
                        //    writer.WriteLine(txtPassword.Text);
                        //}

                        //frmDash frmDash = new frmDash();
                        //frmDash.Owner = this;
                        //frmDash.Show();
                        //txtUsername.Text = "";
                        //txtPassword.Text = "";
                        #endregion
                    }
                    //GlolbalUtil.accept_status = "1";
                }
                else
                {
                    MessageBox.Show("Please Check Username and password");

                }


            }
            catch (Exception ex)
            {
                string filePath = @"D:\RetailButton_Exception.txt";

                using (StreamWriter writer = new StreamWriter(filePath, true))
                {
                    writer.WriteLine("Message :" + ex.Message + "<br/>" + Environment.NewLine + "StackTrace :" + ex.StackTrace +
                       "" + Environment.NewLine + "Date :" + DateTime.Now.ToString());
                    writer.WriteLine(Environment.NewLine + "-----------------------------------------------------------------------------" + Environment.NewLine);
                }
            }
        }
Dinav Ahire
  • 561
  • 7
  • 28
  • 1
    Insted of File.Exists(test + "credentials.txt") use File.Exists(Path.Combine(test, "credentials.txt")). Also StreamWriter writer = new StreamWriter(Path.Combine(test, "credentials.txt"); Otherwise you're trying to write to directory, not to a file. In your code "test" is a folder name, not filename. Also File.Create(Path.Combine(test, "credentials.txt")). – norekhov Jul 01 '15 at 05:09
  • or use String test = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "credentials.txt"); And remove it in File.Exists – norekhov Jul 01 '15 at 05:14
  • IO exception after your changes : The process cannot access the file 'C:\Users\adinav\AppData\Roaming\credentials.txt' because it is being used by another process. – Dinav Ahire Jul 01 '15 at 05:19
  • If file exists using(FileStream fs = File.Create(test)) actually creates and locks the file. Than you try to open it again with StreamWriter. That's why you're receiving it. Remove using(FileStream fs = File.Create(test)). – norekhov Jul 01 '15 at 05:23
  • Sorry, I doubt this question is about improving your code and making it work. You should ask another one like "why this code is not working and how to improve it". But it can be rewritten totally to make it nice and robust. – norekhov Jul 01 '15 at 05:26
  • 1
    Now you see that it doesn't matter if file exists or not. You can remove this check, application will work the same. – norekhov Jul 01 '15 at 05:36

4 Answers4

2

The answer is simple - you shouldn't use absolute path. Choose one of specific system folders depending on what you're doing. Check folders here I suggest using ApplicationData if it's per user files. Or use CommonApplicationData if it's per system files.

That's how most of the applications behave now. Don't try to store app created files in your installation folder cause it's not per user. It's per machine.

It may be even prohibited for your app to write to Program Files cause it's folder is not intended to store application configuration.

An example from msdn on how to use SpecialFolders.

// Sample for the Environment.GetFolderPath method 
using System;

class Sample 
{
    public static void Main() 
    {
    Console.WriteLine();
    Console.WriteLine("GetFolderPath: {0}", 
                 Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
    }
}

Sample how to store info there:

    static void Main(string[] args)
    {
        var file = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "userinfo.txt");
        using (var writer = new StreamWriter(file))
        {
            writer.WriteLine("Hello, World!");
        }
    }
norekhov
  • 2,557
  • 18
  • 34
2

You can also use Application.StartupPath for building you path, it is the path where you executable is placed.

        string credentialFilePath = Path.Combine(Application.StartupPath, "credentials.txt");
        string retailExceptionFilePath = Path.Combine(Application.StartupPath, "RetailButton_Exception.txt");
Yogi
  • 7,598
  • 2
  • 39
  • 56
  • Application.StartupPath can be anything if I specify it when launching your application as a 0 param. There's no general way to detect from where your app was started just because application can be fooled in some ways. – norekhov Jul 01 '15 at 04:28
  • not working. not writing content in `credential.txt` file – Dinav Ahire Jul 01 '15 at 04:28
  • @DinavAhire: Is the file created and blank? Are you getting any error? – Yogi Jul 01 '15 at 04:34
  • Please see this thread http://stackoverflow.com/questions/837488/how-can-i-get-the-applications-path-in-a-net-console-application and dont use Application.StartupPath anymore. In general it's possible to spoof it easily. It's only a "convention" that this variable contains your app path. – norekhov Jul 01 '15 at 04:42
  • @norekhov: Thanks. Actually, `Application` class is part is part of `System.Windows.Forms` namespace, and is not available in other applications like console, and this is what the thread talks of. And since the question is for winform, it is alright to use this in scenario. Of course there are other ways to find paths, and it is more of preference. There is nothing wrong about using any of them. – Yogi Jul 01 '15 at 04:54
  • The thread talks that Environment.GetCommandLineArgs()[0]; which actually is behind Application.StartupPath can be easily spoofed if user launches your app through some exec() or spawn(). It doesn't matter if it's managed or native app. It's system convention which is not mandatory to follow when launching app. That's why this solution is not robust. Ok, most of the time it works. But not always. Moreover storing config or other app created files in "Program Files" is a kinda.. unexpected thing. – norekhov Jul 01 '15 at 04:57
0

You can place your txt files in the same folder with your compiled exe file.

Then, you can use a relative path like this:

File.WriteAllText(@"credentials.txt", String.Empty);

If your application will be installed on:

C:\Program Files\YourApplication\yourapplication.exe

Then it will try to open

C:\Program Files\YourApplication\credentials.txt

Moreover, you can add your txt files to a Visual Studio project and set a property Copy To Output Directory to Copy if newer.
After that your output directory will always have these two files and it will be easier for you to work with it.

Yeldar Kurmangaliyev
  • 30,498
  • 11
  • 53
  • 87
  • is this same like Environment.CurrentDirectory + "filepath" – Dinav Ahire Jul 01 '15 at 04:17
  • Environment.CurrentDirectory could be different path depending on how your app was started. – norekhov Jul 01 '15 at 04:18
  • if i am using Environment.CurrentDirectory, its storing files where .exe is created – Dinav Ahire Jul 01 '15 at 04:20
  • @DinavAhire In short, yes. Using relative path is the same as using `Environment.CurrentDirectory`. However, sometimes `Environment.CurrentDirectory` is not where your exe file stored. It will be the same directory if your application will be run directly or through the shortcut. It also can be a different folder. For example, if you run Windows service or the shortcut "Working directory" will be changed. – Yeldar Kurmangaliyev Jul 01 '15 at 04:21
  • ya right. but i use this scheme then exception comes when i launch my app saying couldn't find path for these files. – Dinav Ahire Jul 01 '15 at 04:23
  • how about Environment.SpecialFolder? – Dinav Ahire Jul 01 '15 at 04:23
0

Just use your application folder, you can use it by Application.StartupPath

try doing this

string yourfilepath = Application.StartupPath + "credentials.txt";
string secondfile = Application.StartupPath + "RetailButton_Exception.txt";
hdkhardik
  • 662
  • 3
  • 22