2009-12-29 3 views
12

Есть ли способ обойти или удалить блокировку файла, удерживаемую другим потоком, не убивая поток?Можно ли обойти блокировку файлов в C#, когда другой поток/процесс имеет необходимость использовать эксклюзивную блокировку?

Я использую стороннюю библиотеку в своем приложении, которая выполняет только для чтения операции над файлом. Мне нужно, чтобы второй поток читал файл в то же время, чтобы извлечь лишние данные, которые сторонняя библиотека не раскрывает. К сожалению, сторонняя библиотека открыла файл, используя блокировку чтения/записи, и поэтому я получаю обычный «Процесс не может получить доступ к файлу ... потому что он используется другим процессом».

Я хотел бы избежать предварительной загрузки всего файла моим потоком, потому что файл большой и может вызвать нежелательные задержки при загрузке этого файла и избыточном использовании памяти. Копирование файла нецелесообразно из-за размера файлов. Во время нормальной работы два потока, попадающих в один и тот же файл, не будут вызывать каких-либо серьезных проблем с конкуренцией/производительностью. Мне не нужна идеальная синхронизация времени между двумя потоками, но они должны читать одни и те же данные за полсекунды друг друга.

Я не могу изменить стороннюю библиотеку.

Есть ли проблемы с этой проблемой?

+6

Замок - это замок - если бы это было, это не было бы блокировкой ... –

+1

И, как и многие замки, некоторые разработчики библиотеки не понимают, что меньше. :-) Я также был бы доволен умной работой. –

+4

Длинный снимок: можете ли вы открыть этот файл в качестве общей _before_ вашей сторонней библиотеки? Возможно, они внедрили некоторый резервный механизм. –

ответ

5

Если вы начинаете messing with the underlying file handle, вы можете разблокировать порты, проблема в том, что поток, обращающийся к файлу, не предназначен для обработки такого рода несанкционированного доступа и может закончиться сбоем.

Моей надежной рекомендацией было бы исправить стороннюю библиотеку, все, что вы можете сделать, и, вероятно, взорвется в реальных условиях.

1

Это не касается вашей ситуации напрямую, но такой инструмент, как Unlocker, делает то, что вы пытаетесь сделать, но через пользовательский интерфейс Windows.

2

Одним словом, вы не можете ничего сделать по поводу блокировки файла сторонним пользователем. Вы можете уйти от ответа Ричарда Е выше, в котором упоминается утилита Unlocker.

После того, как сторонняя сторона открывает файл и устанавливает блокировку на нем, базовая система предоставит сторонней блокировке, чтобы никто другой процесс не смог получить к ней доступ. На этом есть два поезда.

  • Использование DLL-инъекции для исправления кода, чтобы явно установить блокировку или отключить ее. Это может быть опасно, поскольку вы будете возиться с стабильностью другого процесса и, возможно, в конечном итоге разрушите процесс и проявите горе. Подумайте об этом, базовая система отслеживает файлы, открытые процессом. DLL-инъекция в точке и исправление кода - для этого требуются технические знания, чтобы определить, какой процесс вы хотите внедрить во время выполнения и изменить флаги при перехвате вызова API Win32 OpenFile(...).
  • Поскольку это было помечено как .NET, почему бы не разобрать источник сторонних файлов в .il и изменить флаг блокировки для совместного использования, перестроить библиотеку, перекомпилировав все файлы .il обратно в DLL , Это, конечно же, потребует корень вокруг кода, где открытие файла происходит где-то в каком-то классе.

Посмотрите на подкаст here. И посмотрите здесь, где объясняется, как сделать второй вариант, выделенный выше, here.

Надеюсь, это поможет, С уважением, Tom.

1

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

Поэтому я думал, что уже следующая лучшая вещь, просто ждать своей очереди и опрос, пока файл не заблокирован: https://stackoverflow.com/a/11060322/495455


Я не думаю, что это второй совет поможет, но ближе всего (что я знаю) будет DemandReadFileIO:

IntSecurity.DemandReadFileIO(filename); 

internal static void DemandReadFileIO(string fileName) 
{ 
    string full = fileName;    
    full = UnsafeGetFullPath(fileName); 
    new FileIOPermission(FileIOPermissionAccess.Read, full).Demand(); 
} 
1

Я действительно думаю, что это проблема, которая может быть решена с помощью C++. Это является раздражает, но по крайней мере это работает (как описано здесь: win32 C/C++ read data from a "locked" file)

Шаги:

  1. Открыть файл перед третьей библиотеке с fsopen и флаг _SH_DENYNO
  2. Откройте файл с третьей библиотекой
  3. Прочитайте файл в коде

Вы можете быть заинтересованы в этих ссылках, а также:

  1. Вызов C++ из C# (Possible to call C++ code from C#?)
  2. Внутренняя ссылка с этого поста с образцом (http://blogs.msdn.com/b/borisj/archive/2006/09/28/769708.aspx)
1

Вы пробовали сделать фиктивную копию файла перед вашей библиотеки третьей стороной получает его ... затем, используя фактическую копию для ваших манипуляций, логически это будет рассмотрено только в том случае, если файл, о котором мы говорим, довольно мал. но это своего рода чит :) Удачи

1

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

Смежные вопросы