Sergey Alexandrovich Kryukov
По умолчанию файл открыт для исключительного использования, хотя только один дескриптор файла. Если какой-то другой процесс откроет его, у вас будет исключение при попытке открыть его снова. Существует возможность открыть файл для множественного доступа, но это редко бывает, и это не тот случай, который вы описали.
Вы не сможете закрыть файл, если не прекратите процесс "оскорбления".
Прежде всего, подобный вопрос задавался здесь много раз, и из этого опыта я знаю: в большинстве случаев процесс блокировки-это ваш собственный процесс. Вы могли забыть избавиться/закрыть что-то в том же приложении. Итак, прежде всего, проверьте это. Чтобы изучить эту возможность, пожалуйста, посмотрите мой прошлый ответ:
Сняв ручку в C#[^].
В тех же случаях вам действительно нужно исследовать, какой процесс содержит какой файл. Для этого я рекомендую использовать одну утилиту из Sysinternals Suite. Этот набор утилит (ранее от Компании winternals компания, в настоящее время в Microsoft) является обязательным для любого разработчика, пожалуйста, смотрите:
http://technet.microsoft.com/en-us/sysinternals/bb842062[^],
http://technet.microsoft.com/en-us/sysinternals/bb545027[^].
Утилита, которая вам нужна, это "handle.exe", пожалуйста, смотрите:
http://technet.microsoft.com/en-us/sysinternals/bb896655[^].
В вашем случае вы используете его с параметром имени файла:
handle.exe <file_name>
Эта утилита будет сканировать все виды дескрипторов, а не только дескрипторы файлов. Для файла он будет сканировать все дескрипторы файлов, соответствующие имени файла (поэтому он не должен быть полным именем пути), и возвращать информацию, достаточную для идентификации каждого процесса, включая его имя.
pid Таким образом, если вам нужна дополнительная информация о рассматриваемом процессе, вы также можете использовать другие утилиты Sysinternals, в частности, его
Исследователь Процессов:
http://technet.microsoft.com/en-us/sysinternals/bb896653[
^].
[Правка #1]
Теперь, если вы просто хотите проверить, открыт ли файл уже каким-то процессом в данный момент (но почему?), я обычно советую очень простую вещь. Это хорошая идея-использовать наступательное Программирование вместо оборонительного. Вы можете просто работать с файлом, как будто он не заблокирован. Бутерброд этой части кода в блоке try-catch-finally. Если блок бросает код в часть catch, это означает, что файл был использован другим процессом. Это абсолютно безопасно.
Делать что-то другое очень трудно и вряд ли может оправдать усилия. Кроме того, он сильно зависит от системы и, конечно же, потребует P/Invoke. Вы полностью убьете независимость вашего кода от платформы, если попытаетесь это сделать.
[Правка #2]
В принципе, можно было бы запустить и другой вариант handle.exe через
System.Diagnostics.Process.Start
Вам также нужно будет перенаправить
StandardOutput
вашего процесса, чтобы захватить и извлечь результат диагностики. Образец перенаправления можно найти здесь:
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput.aspx[
^].
Однако такой подход далек от элегантности. И если вам нужно развернуть свой продукт, это будет какая-то проблема (юридическая, техническая… третья сторона - это третья сторона).
Удачи,
—СА