В сервисе, который перемещал по полученному сообщению директорию из одного места в другое, часто была ошибка перемещения. Самая распространенная - файл в директории кем-то открыт. Вопроса два - какой файл и кто держит.
Если на второй вопрос ответит скорей AD администратор, то информацию о том, какой файл открыт, можно получить.
Встроенного в .Net метода для подобного не нашел, но придумал Wokaround.
Перемещение папки в .Net выполняется методом Move (System.IO.Directory)
void Directory.Move(oldPath, newDest);
Если что-то не вышло, будет ошибка. В случае ошибки доступа к директории будет Exceoption типа IOException. Потому обернем вызов Move в try ... catch, обработав соответствующее исключение.
try
{
Directory.Move(oldPath, newDest);
}
catch(IOException ioex)
{
string lockedFile = FindLockedFiles(oldPath);
_logger.LogError($"Failed to move the directory {oldPath} to {newPath}. The file {lockedFile} is locked. {ioex.Message}");
}
catch (Exception ex)
{
_logger.LogError($"Failed to move the directory {oldPath} to {newPath}. {ex.Message}");
}
Реализация метода FindLockedFiles заключается в том, чтобы попытаться инклюзивно открыть файлы из директории. Если это не получится, то этот файл используется. Отмечу, что метод выполняется только при ошибке IOException.
private string FindLockedFiles(string directoryPath)
{
string result = string.Empty;
foreach (string file in Directory.GetFiles(directoryPath, "*", SearchOption.AllDirectories))
{
try
{
// Attempt to open the file in exclusive mode
using (FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.None))
{
Console.WriteLine($"File is accessible: {file}");
}
}
catch (IOException)
{
Console.WriteLine($"File is locked: {file}");
result = file;
return result;
}
catch (Exception ex)
{
Console.WriteLine($"Unexpected error with file {file}: {ex.Message}");
result = file;
return result;
}
}
return result;
}
В моей реализации я сразу возвращаю первый открытый кем-то или чем-то файл. Зачастую, этого достаточно для понимания.

