Member 12076824 Ответов: 4

C# удаление файлов, используемых другим процессом


I am not expert. I am trying to delete the files from the directory at button click. I have windows application which have folders populated in combobox1 and files populated in combobox2. I need to delete the selected folder from combobox1 and files within the folder. I am getting error cannot delete the file as it's being used by another process. Basically application can be used by multiple users and one of the folder I am trying to delete might be listed on the second users combobox. I need to delete the files even if its listed in second users combobox, as I have another logic that doesn't allow the user to select the combobox item selected by first user.

Ошибка вызвана из-за того же имени файла в другой папке(поскольку у меня есть изображения во всех папках с одинаковыми именами, но разными изображениями), она не вызвана из-за того, что папку пытаются удалить. Если пользователь выбирает пакет, который уже удален, у меня есть логика, чтобы проверить, если этот конкретный каталог больше не существует, удалить из combobox и перейти к следующему пакету или первому пакету, если удаленный элемент был последним.

    string batchrem = "";
    selindex02 = comboBox1.SelectedIndex;
    batchrem = comboBox1.Text;

    string dir_name = comboBox1.Text.ToString().Substring(0, 12);
    string path1 = strval + dir_name + "\\";
    //string path1 ="C:\\Project\\" + dir_name + "\\";
    DirectoryInfo di = new DirectoryInfo(path1);
    SqlConnection conn001 = new SqlConnection();
    conn001.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString;
    SqlCommand comd012 = new SqlCommand("GetBatch", conn001);
    comd012.CommandType = CommandType.StoredProcedure;
    comd012.CommandText = "usp_CAMR_Delete_MarriageInfo";
    comd012.Connection = conn001;
    comd012.Parameters.AddWithValue("@batch_name", comboBox1.Text.ToString().Substring(0, 12));
    comd012.Parameters.AddWithValue("@ERR_CODE", 0);
    comd012.Parameters.AddWithValue("@ERR_MSG", 0);
    comd012.Parameters.AddWithValue("@TABLE_NAME", "");
    try
    {
        SqlConnection con = new SqlConnection();
        con.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString;
        SqlCommand cmd = new SqlCommand("BatchUpdate", con);
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "usp_CAMR_UnlockedBatchName";
        //cmd.Connection = con;
        con.Open();
        cmd.Parameters.AddWithValue("@Batch_Name", comboBox1.Text.ToString().Substring(0, 12));
        cmd.Parameters.AddWithValue("@lst_mod_userid", Environment.UserName);
        cmd.Parameters.AddWithValue("@ERR_CODE", 0);
        cmd.Parameters.AddWithValue("@ERR_MSG", 0);
        cmd.Parameters.AddWithValue("@TABLE_NAME", 0);
        cmd.ExecuteNonQuery();
        con.Close();
        con.Dispose();
        conn001.Open();
        comd012.ExecuteNonQuery();
    }
    catch (Exception ex)
    {
        {
            oErrorLog.WriteErrorLog(ex.ToString());
        }
        lblerror.Text = "Please contact support team";
    }
    finally
    {
        conn001.Close();
        conn001.Dispose();
        if (di.Exists)
        {
            try
            {
                if (comboBox1.SelectedIndex < comboBox1.Items.Count - 1)
                {
                    comboBox1.SelectedIndex = selindex02 + 1;
                }
                else
                {
                    // comboBox1.Items.Remove(batchrem);
                    comboBox1.SelectedIndex = 0;
                }
                foreach (FileInfo fi in di.GetFiles())
                {

                    System.GC.Collect();
                    System.GC.WaitForPendingFinalizers();
                    fi.IsReadOnly = false;
                    fi.Delete();
                }
                di.Delete();
                comboBox1.Items.Remove(batchrem);
            }
            catch (Exception ex)
            {

                lblerror.Text = ex.Message();
            }
        }
    }
}


Что я уже пробовал:

Я попробовал использовать
System.GC.Collect();
System.GC.WaitForPendingFinalizers();


Он отлично работает, если есть только один пользователь, использующий приложение

kaooodate

Работайте на меня, спасибо

4 Ответов

Рейтинг:
2

Clifford Nelson

Вы можете удалить их при перезагрузке. Вам понадобятся объявления P/Invoke для MoveFileEx:

[Flags]
internal enum MoveFileFlags
{
    None = 0,
    ReplaceExisting = 1,
    CopyAllowed = 2,
    DelayUntilReboot = 4,
    WriteThrough = 8,
    CreateHardlink = 16,
    FailIfNotTrackable = 32,
}

internal static class NativeMethods
{
    [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
    public static extern bool MoveFileEx(
        string lpExistingFileName,
        string lpNewFileName, 
        MoveFileFlags dwFlags);
}

if (!NativeMethods.MoveFileEx("a.txt", null, MoveFileFlags.DelayUntilReboot))
{
    Console.Error.WriteLine("Unable to schedule 'a.txt' for deletion");
}


Рейтинг:
1

Patrice T

Цитата:
Я получаю ошибку не могу удалить файл, так как он используется другим процессом.
Короткий ответ: Нет, вы не можете, windows не позволит этого.


Рейтинг:
0

Dave Kreskowiak

Как говорится в ошибке, вы не можете удалить файл, используемый каким-либо процессом, а также удалить папку, в которой открыт файл.

Комбо-боксы не имеют к этому никакого отношения. Это просто контейнеры, которые показывают строку, в вашем случае имя файла/папки.

Файлы фактически используются каким-то процессом. Вы не можете удалить их до тех пор, пока каждый процесс, который имеет открытый файл, не закроет его.

Да, можно удалить файл, который используется, но это влечет за собой определенные последствия. Вы вызовете сбой приложения, в котором был открыт файл, и вы вызовете нестабильность системы, что в конечном итоге приведет к сбою Windows.


Member 12076824

Ошибка вызвана из-за того же имени файла в другой папке(поскольку у меня есть изображения во всех папках с одинаковыми именами), она не вызвана из-за того, что папку пытаются удалить. Что касается сбоя приложения, то у меня есть логика, чтобы проверить, если этот конкретный каталог больше не существует, удалить из combobox и перейти к следующему пакету или первому пакету, если удаленный элемент был последним.

Dave Kreskowiak

В контексте вашего первоначального сообщения ваш комментарий не имел абсолютно никакого смысла.

Member 12076824

Я понял это сегодня и добавил это к вопросу. Спасибо за ваш ответ

Rob Philpott

Это интересно. Как можно удалить файл, используемый другим процессом?

Dave Kreskowiak

Я этого не говорю. Настоящие "я должен иметь" люди будут искать его в Google.
Просто предупреждаю, это некрасиво.

Rob Philpott

Коммерческая тайна, а? Продолжай, ты можешь рассказать мне. Включает ли это переписывание операционной системы?

Dave Kreskowiak

Нет. Силу можно использовать во благо и злоупотреблять ею во зло. Я бы предпочел не говорить об этом, опасаясь, что техника будет использована неподобающим образом. а потом тебя обвинят в этом.

Рейтинг:
0

Clifford Nelson

Вы можете, но это должно быть сделано при перезагрузке, так что вы ошибаетесь. Существует также способ принудительного использования, и это известно, потому что существует приложение, которое будет удалять даже заблокированные файлы: IObit Unlocker, решение проблем "восстановления файлов или папок" в Windows 8, 7, Vista, XP, 10 - IObit[^]


Richard Deeming

Неужели? Два новых решения вопроса 18-месячной давности?

Решение 3 было хорошим дополнением, но действительно ли нужно было публиковать второе решение?