Использование File.AppendAllText приводит к ошибке «Процесс не может получить доступ к файлу, который уже используется» - PullRequest
8 голосов
/ 26 марта 2012

Я пишу простую программу кейлоггер (для не злонамеренных целей).

Примечание: Это с клиентским профилем .net 4.0

Всякий раз, когда я запускаю программу, я получаю эту ошибку:

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

Вот мой основной код:

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));
                }
            }
        }
    }
}

Почему это происходит? Это было нормально, когда я использовал это заявление для записи в файл:

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

Но он перестал работать, когда я переключился на простое использование:

File.AppendAllText(Program.file, string.Format("texthere");

1 Ответ

27 голосов
/ 26 марта 2012

Я вижу

 File.Create(Program.file);

, который является ненужным и, вероятно, является прямой проблемой здесь.

Он не только создает пустой файл, но также открывает и возвращает объект FileStream, который вы нигде не закрываете.Открытый FileStream не доступен для совместного использования, поэтому он вызывает метод AppendAllText () завершиться ошибкой.

Просто удалите эту строку, AppendAllText() включает логику для создания файла, если он еще не существует

...