diff --git a/SearchFiles/Program.cs b/SearchFiles/Program.cs index 4c69319..1d8232a 100644 --- a/SearchFiles/Program.cs +++ b/SearchFiles/Program.cs @@ -1,4 +1,5 @@ using System.Net.NetworkInformation; +using System.Diagnostics; class FileSearchProgram { @@ -12,9 +13,11 @@ class FileSearchProgram Console.WriteLine("Программа поиска и удаления папки программы на доменных компьютерах"); LogToFile("Программа поиска и удаления папки программы на доменных компьютерах"); - string fileName = "DowntimeClassifier.exe"; - string folderToDelete = ""; - string searchPath = "D:\\lrpo\\downtimeclassifier"; + string targetFileName = "DowntimeClassifier.exe"; + string targetProcessName = Path.GetFileNameWithoutExtension(targetFileName); + string targetFolderPath = "D:\\lrpo\\DowntimeClassifier"; + string targetFolderName = Path.GetFileName(targetFolderPath.TrimEnd('\\')); + string parentFolderPath = Path.GetDirectoryName(targetFolderPath.TrimEnd('\\'))!; string computersFile = "computers.txt"; try @@ -53,45 +56,69 @@ class FileSearchProgram Console.WriteLine($"\n{checkingMsg}"); LogToFile(checkingMsg); - string uncPath = $"\\\\{computer}\\{searchPath.Replace(":", "$")}"; + string uncFolderPath = $"\\\\{computer}\\{targetFolderPath.Replace(":", "$")}"; + string uncParentPath = $"\\\\{computer}\\{parentFolderPath!.Replace(":", "$")}"; - if (!Directory.Exists(uncPath)) - { - string pathError = $"Путь {uncPath} недоступен на компьютере {computer}"; - Console.WriteLine(pathError); - LogToFile(pathError); - continue; - } - - // Режим 1 или 3: поиск файла + // Режим 1 или 3: поиск файла внутри папки if (mode == "1" || mode == "3") { - bool fileFound = SearchFiles(uncPath, fileName); - - if (!fileFound) + if (!Directory.Exists(uncFolderPath)) { - string notFoundMsg = $"Файл {fileName} не найден на компьютере {computer}"; - Console.WriteLine(notFoundMsg); - LogToFile(notFoundMsg); + string pathError = $"Путь {uncFolderPath} недоступен на компьютере {computer}"; + Console.WriteLine(pathError); + LogToFile(pathError); + } + else + { + bool fileFound = SearchFiles(uncFolderPath, targetFileName); + + if (!fileFound) + { + string notFoundMsg = $"Файл \"{targetFileName}\" не найден на компьютере {computer}"; + Console.WriteLine(notFoundMsg); + LogToFile(notFoundMsg); + } } } // Режим 2 или 3: удаление папки if (mode == "2" || mode == "3") { - DeleteFolder(uncPath, folderToDelete, computer); + if (!Directory.Exists(uncParentPath)) + { + string pathError = $"Родительский путь {uncParentPath} недоступен на компьютере {computer}"; + Console.WriteLine(pathError); + LogToFile(pathError); + } + else + { + // Сначала убиваем все процессы, которые могут блокировать файлы + KillProcessesInFolderOnComputer(computer, uncParentPath, targetFolderName); + + // Затем удаляем папку + DeleteFolderOnComputer(uncParentPath, targetFolderName, computer); + } } // Режим 4: поиск папки if (mode == "4") { - bool folderFound = SearchFolder(uncPath, folderToDelete); - - if (!folderFound) + if (!Directory.Exists(uncParentPath)) { - string notFoundMsg = $"Папка \"{folderToDelete}\" не найдена на компьютере {computer}"; - Console.WriteLine(notFoundMsg); - LogToFile(notFoundMsg); + string pathError = $"Родительский путь {uncParentPath} недоступен на компьютере {computer}"; + Console.WriteLine(pathError); + LogToFile(pathError); + } + else + { + bool folderFound = SearchFolder(uncParentPath, targetFolderName); + + if (!folderFound) + { + string notFoundMsg = $"Папка \"{targetFolderName}\" не найдена на компьютере {computer}"; + Console.WriteLine(notFoundMsg); + LogToFile(notFoundMsg); + } } } } @@ -136,6 +163,121 @@ class FileSearchProgram } } + static void KillProcessesInFolderOnComputer(string computerName, string parentUncPath, string folderName) + { + try + { + string fullFolderPath = Path.Combine(parentUncPath, folderName); + + if (!Directory.Exists(fullFolderPath)) + { + Console.WriteLine($"Папка {fullFolderPath} не найдена на компьютере {computerName}, пропускаем убийство процессов"); + LogToFile($"Папка {fullFolderPath} не найдена на компьютере {computerName}, пропускаем убийство процессов"); + return; + } + + // Рекурсивно собираем все exe-файлы в папке + List exeFiles = new List(); + CollectExeFiles(fullFolderPath, exeFiles); + + if (exeFiles.Count == 0) + { + Console.WriteLine($"Не найдено exe-файлов в папке {fullFolderPath} на компьютере {computerName}"); + LogToFile($"Не найдено exe-файлов в папке {fullFolderPath} на компьютере {computerName}"); + return; + } + + // Убиваем каждый уникальный процесс + HashSet killedProcesses = new HashSet(StringComparer.OrdinalIgnoreCase); + foreach (string exePath in exeFiles) + { + string processName = Path.GetFileNameWithoutExtension(exePath); + if (killedProcesses.Add(processName)) + { + KillSingleProcessOnComputer(computerName, processName); + } + } + } + catch (Exception ex) + { + string killError = $"Ошибка при убийстве процессов в папке {folderName} на {computerName}: {ex.Message}"; + Console.WriteLine(killError); + LogToFile(killError); + } + } + + static void CollectExeFiles(string path, List exeFiles) + { + try + { + foreach (string file in Directory.GetFiles(path, "*.exe")) + { + exeFiles.Add(file); + } + + foreach (string dir in Directory.GetDirectories(path)) + { + CollectExeFiles(dir, exeFiles); + } + } + catch + { + // Если нет доступа к какой-то папке — пропускаем + } + } + + static void KillSingleProcessOnComputer(string computerName, string processName) + { + try + { + Console.WriteLine($"Завершаем процесс \"{processName}\" на компьютере {computerName}..."); + LogToFile($"Завершаем процесс \"{processName}\" на компьютере {computerName}..."); + + ProcessStartInfo psi = new ProcessStartInfo + { + FileName = "taskkill", + Arguments = $"/S {computerName} /IM {processName}.exe /F", + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + using (Process process = Process.Start(psi)!) + { + string output = process.StandardOutput.ReadToEnd(); + string error = process.StandardError.ReadToEnd(); + process.WaitForExit(10000); + + if (process.ExitCode == 0) + { + string successKill = $"Процесс \"{processName}\" успешно завершён на компьютере {computerName}"; + Console.WriteLine(successKill); + LogToFile(successKill); + } + else if (error.Contains("not found", StringComparison.OrdinalIgnoreCase) || + error.Contains("does not exist", StringComparison.OrdinalIgnoreCase) || + error.Contains("not running", StringComparison.OrdinalIgnoreCase)) + { + Console.WriteLine($"Процесс \"{processName}\" не запущен на компьютере {computerName}"); + LogToFile($"Процесс \"{processName}\" не запущен на компьютере {computerName}"); + } + else + { + string warnKill = $"Не удалось завершить процесс \"{processName}\" на {computerName}. Ошибка: {error.Trim()}"; + Console.WriteLine(warnKill); + LogToFile(warnKill); + } + } + } + catch (Exception ex) + { + string killError = $"Ошибка при попытке завершить процесс \"{processName}\" на {computerName}: {ex.Message}"; + Console.WriteLine(killError); + LogToFile(killError); + } + } + static bool SearchFiles(string path, string fileName) { try @@ -204,7 +346,7 @@ class FileSearchProgram } } - static void DeleteFolder(string basePath, string folderName, string computerName) + static void DeleteFolderOnComputer(string basePath, string folderName, string computerName) { try {