Using File.AppendAllText causes a "Process cannot access the file, already in use" error
Asked Answered
N

1

15

I am writing a simple keylogger program (for non-malicious purposes).

Note: This is with .net 4.0 Client Profile

Whenever I start the program, I get this error:

The process cannot access the file 'C:\Users\.. ..\bin\Debug\log.log' because it is being used by another process.

Here is my main code:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using System.IO;
using System.Text;

namespace Logger
{
    public partial class MainForm : Form
    {
        public string cWin = null;
        public static string nl = Environment.NewLine;

        public MainForm()
        {
            InitializeComponent();
        }

        public static DialogResult AskOverwrite()
        {
            DialogResult result = MessageBox.Show("Log already exists. Overwrite?", 
                "Overwrite?", 
                MessageBoxButtons.YesNo, 
                MessageBoxIcon.Question);

            return result;
        }

        private void MainForm_Resize(object sender, EventArgs e)
        {

             if (FormWindowState.Minimized == this.WindowState)
             {
                  systray.Visible = true;
                  this.Hide();    
             }
             else if (FormWindowState.Normal == this.WindowState)
             {
                  systray.Visible = false;
             }
        }

        private void SystrayMouse_DoubleClick(object sender, MouseEventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
        }

        private void HookManager_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (Program.run)
            {
                output.AppendText(string.Format(e.KeyChar.ToString()));
                File.AppendAllText(Program.file, e.KeyChar.ToString());
            }
        }

        private void Start_Click(object sender, EventArgs e)
        {
            if (!Program.run)
            {
                if (File.Exists(Program.file))
                {
                    if (AskOverwrite() == DialogResult.Yes)
                    {
                        File.Create(Program.file);
                    }
                }

                Program.run = true;
                output.AppendText(string.Format("Logging started - {1}{0}", nl, System.DateTime.Now));
                File.AppendAllText(Program.file, string.Format("Logging started - {1}{0}", nl, System.DateTime.Now));
            }
            else
            {
                output.AppendText(string.Format("Logging already started!{0}", nl));
            }
        }

        private void Stop_Click(object sender, EventArgs e)
        {
            if (Program.run)
            {
                Program.run = false;
                output.AppendText(string.Format("{0}Logging stopped - {1}{0}", nl, System.DateTime.Now));
                File.AppendAllText(Program.file, string.Format("{0}Logging stopped - {1}{0}", nl, System.DateTime.Now));
            }
            else
            {
                output.AppendText(string.Format("Logging already stopped!{0}", nl));
            }
        }

        private void getWindowTimer_Tick(object sender, EventArgs e)
        {
            if (cWin != CurrentWindow.GetActiveWindow() &&Program.run)
            {
                cWin = CurrentWindow.GetActiveWindow();
                if (cWin != null)
                {
                    output.AppendText(string.Format("{0}Window - {1}{0}", nl, cWin));
                    File.AppendAllText(Program.file, string.Format("{0}Window - {1}{0}", nl, cWin));
                }
            }
        }
    }
}

Why is this happening? It was fine when I was using this statement to write to the file:

using (StreamWriter sr = new StreamWriter(Program.file))
{
    sr.Write(string.Format("texthere");
}

But it stopped working when I switched over to simply using:

File.AppendAllText(Program.file, string.Format("texthere");
Navarra answered 26/3, 2012 at 18:8 Comment(2)
What version of .Net are you targeting?Activity
This is going to sound obvious, but you don't have your log file open in another program while you're trying to write to it?Fawcett
F
34

I see a

 File.Create(Program.file);

which is unnecessary and probably the direct problem here.

It does not just create an empty file but it also opens and returns a FileStream object that you do not close anywhere. The opened FileStream is not shareable so it causes AppendAllText() to fail.

Just remove that line, AppendAllText() includes the logic to create the file if it does not already exist

Froe answered 26/3, 2012 at 18:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.