Автор |
Сообщение |
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
Сергей_К писал(а): Но и это решение выглядит как то костыляво. Вот если через winAPI как-нибудь... Открыть файл на запись и есть самый простой способ узнать, открыт ли файл на запись другим процессом или нет. Если ошибка - либо файл не существует либо уже открыт на запись. Можно конечно через недокументированные функции добраться до списка хэндлов всех открытых файлов и искать там нужный файл - но это уже будет не так тривиально и просто.
[quote="Сергей_К"]Но и это решение выглядит как то костыляво. Вот если через winAPI как-нибудь...[/quote] Открыть файл на запись и есть самый простой способ узнать, открыт ли файл на запись другим процессом или нет. Если ошибка - либо файл не существует либо уже открыт на запись. Можно конечно через недокументированные функции добраться до списка хэндлов всех открытых файлов и искать там нужный файл - но это уже будет не так тривиально и просто.
|
|
|
|
Добавлено: Вт ноя 01, 2011 17:44 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
Если тема еще актуальна, то позвольте, как говорится, сказать: registration писал(а): Код: FOUND-FULLPATH R/W OPEN-FILE-SHARED GetLastError 32 <> \ 32 -код ошибки ERROR_SHARING_VIOLATION UNTIL CLOSE-FILE DROP
Здесь не совсем так. В документации крона вообще ничего не сказано о слове OPEN-FILE-SHARED. Но из приведенного там примера можно сделать вывод, что оно возвращает дескриптор файла (FID), открытого для немонопольного доступа. Там же этот дескрипттор присваивается переменной. А слово CLOSE-FILE используется соответствоенно с этим же дескриптором (или fileID). Т.е. не хватает переменной для дискриптора, открывающего и закрывающего файл. (отсюда, видимо, и проблема стека, т.к. слово возвращает дискриптор) В кроне так: Код: S" test.txt" R/O OPEN-FILE-SHARED THROW list-file ! \ заносим ID файла в переменную, чтобы иметь возможность с ним работать для записи, чтения и пр. Далее list-file @ CLOSE-FILE DROP \ закрываем файл по его ID
Вот. Ну и еще несколько замечаний: Если открывать файл словом OPEN-FILE-SHARED, то каким образом мы увидим, что он занят? Т.е. он может быть занят занят процессом, но не монопольно, т.е. мы не поймем, можно ли его перемещать собственно? Вот если его открыть словом OPEN-FILE (т.е. использовать монопольный доступ), то, отловив ошибку, поймем, что файл уже занят. И, поняв, что он занят, сделаем паузу, проверим еще раз и т.д. пока не освободится. Ну вот как то так, как я думаю. Но и это решение выглядит как то костыляво. Вот если через winAPI как-нибудь... Но эта тема для меня темный лес. Однако такая простенькая прога Unlocker показывает все процессы, которые работают с файлом и даже может их легко разблокировать. Не знаю, сделано ли в ней средствами системы или как то другим способом.
Если тема еще актуальна, то позвольте, как говорится, сказать: [quote="registration"] [code] FOUND-FULLPATH R/W OPEN-FILE-SHARED GetLastError 32 <> \ 32 -код ошибки ERROR_SHARING_VIOLATION UNTIL CLOSE-FILE DROP [/code] [/quote] Здесь не совсем так. В документации крона вообще ничего не сказано о слове OPEN-FILE-SHARED. Но из приведенного там примера можно сделать вывод, что оно возвращает дескриптор файла (FID), открытого для немонопольного доступа. Там же этот дескрипттор присваивается переменной. А слово CLOSE-FILE используется соответствоенно с этим же дескриптором (или fileID). Т.е. не хватает переменной для дискриптора, открывающего и закрывающего файл. (отсюда, видимо, и проблема стека, т.к. слово возвращает дискриптор) В кроне так: [code]S" test.txt" R/O OPEN-FILE-SHARED THROW list-file ! \ заносим ID файла в переменную, чтобы иметь возможность с ним работать для записи, чтения и пр. Далее list-file @ CLOSE-FILE DROP \ закрываем файл по его ID [/code] Вот. Ну и еще несколько замечаний: Если открывать файл словом OPEN-FILE-SHARED, то каким образом мы увидим, что он занят? Т.е. он может быть занят занят процессом, но не монопольно, т.е. мы не поймем, можно ли его перемещать собственно? Вот если его открыть словом OPEN-FILE (т.е. использовать монопольный доступ), то, отловив ошибку, поймем, что файл уже занят. И, поняв, что он занят, сделаем паузу, проверим еще раз и т.д. пока не освободится. Ну вот как то так, как я думаю. Но и это решение выглядит как то костыляво. Вот если через winAPI как-нибудь... Но эта тема для меня темный лес. Однако такая простенькая прога Unlocker показывает все процессы, которые работают с файлом и даже может их легко разблокировать. Не знаю, сделано ли в ней средствами системы или как то другим способом.
|
|
|
|
Добавлено: Вт ноя 01, 2011 14:31 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
Забыл добавить, что сеть Microsoft без домена
Забыл добавить, что сеть Microsoft без домена
|
|
|
|
Добавлено: Чт июл 21, 2011 04:17 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
Очень похожая ситуация. Пресловутый usb.wsf создан на сетевом диске одной из рабочих станций. Все WS обходить - долгая песня (хотя, видимо, придется). А работать мешает. Может есть возможность определить в чьем реестре он прописан? Ответ, если можно, по E-mail: 696944.110@mail.ruЗаранее спасибо. Алексей Кашкаров
Очень похожая ситуация. Пресловутый usb.wsf создан на сетевом диске одной из рабочих станций. Все WS обходить - долгая песня (хотя, видимо, придется). А работать мешает. Может есть возможность определить в чьем реестре он прописан? Ответ, если можно, по E-mail: 696944.110@mail.ru Заранее спасибо. Алексей Кашкаров
|
|
|
|
Добавлено: Чт июл 21, 2011 04:11 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
итак, по коду: registration писал(а): CLOSE-FILE ( fileid --> ior ) \ А ниже мне непонятно, что для THROW \ на стеке должно быть и что останется, \ на стеке когда THROW отработает? THROW THROW снимает с вершины стека число, если оно отлично от нуля, выполняется код, вызывающий исключение, если нуль - управление передается коду, расположеному за THROW.
итак, по коду: [quote="registration"]CLOSE-FILE ( fileid --> ior ) \ А ниже мне непонятно, что для THROW \ на стеке должно быть и что останется, \ на стеке когда THROW отработает? THROW[/quote] THROW снимает с вершины стека число, если оно отлично от нуля, выполняется код, вызывающий исключение, если нуль - управление передается коду, расположеному за THROW.
|
|
|
|
Добавлено: Пт мар 11, 2011 20:01 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
registration писал(а): 1. Перед IF на стеке отсутствует результат операции сравнения ( flag ). В IF входим со значением ior оставшимся от OPEN-FILE-SHARED Вопрос: это и будет, в данном случае, flag для IF? да, в Форте IF реагирует на 0, либо на отличное от него значение, а флаги TRUE = -1 FALSE = 0. Т.е. не так как в Си или Паскале!!! Впрочем, я это уже описывал. registration писал(а): 2. Мне непонятно, что для THROW на стеке должно быть и что останется, на стеке когда THROW отработает? опять же уже было описано и CATCH и THROWчуть позже продолжу
[quote="registration"]1. Перед IF на стеке отсутствует результат операции сравнения ( flag ). В IF входим со значением ior оставшимся от OPEN-FILE-SHARED Вопрос: это и будет, в данном случае, flag для IF?[/quote] да, в Форте IF реагирует на 0, либо на отличное от него значение, а флаги TRUE = -1 FALSE = 0. Т.е. не так как в Си или Паскале!!! Впрочем, я это [url=http://www.fforum.winglion.ru/viewtopic.php?f=34&t=1091]уже описывал[/url].
[quote="registration"]2. Мне непонятно, что для THROW на стеке должно быть и что останется, на стеке когда THROW отработает?[/quote] опять же уже [url=http://www.fforum.winglion.ru/viewtopic.php?f=34&t=1655]было описано[/url] и [url=http://www.fforum.winglion.ru/viewtopic.php?f=34&t=1632]CATCH и THROW[/url] чуть позже продолжу
|
|
|
|
Добавлено: Пт мар 11, 2011 18:38 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
Спасибо, mOleg, за потраченное на меня время. Исправил стековую нотацию. Возникли ещё вопросы. 1. Перед IF на стеке отсутствует результат операции сравнения ( flag ). В IF входим со значением ior оставшимся от OPEN-FILE-SHARED Вопрос: это и будет, в данном случае, flag для IF? 2. Мне непонятно, что для THROW на стеке должно быть и что останется, на стеке когда THROW отработает? 3. Для чего вообще THROW в данном коде? Код: FOUND-FULLPATH R/W OPEN-FILE-SHARED ( --> fileid ior ) DUP ( fileid ior --> fileid ior ior ) \ перед IF на стеке отсутствует результат операции \ сравнения ( flag ). В IF входим со значением ior \ оставшимся от OPEN-FILE-SHARED \ Вопрос: это и будет, в данном случае, flag для IF? IF ( fileid ior ior --> fileid ior ) \ если ior <> 0 NIP ( fileid ior --> ior ) 32 ( ior --> ior 32 ) <> ( ior 32 --> flag ) ELSE ( fileid 0 0 --> fileid 0 ) \ если ior OPEN-FILE-SHARED = 0 \ т.е. файл нормально открылся DROP ( fileid 0 --> fileid ) CLOSE-FILE ( fileid --> ior ) \ А ниже мне непонятно, что для THROW \ на стеке должно быть и что останется, \ на стеке когда THROW отработает? THROW TRUE THEN
Спасибо, [b]mOleg[/b], за потраченное на меня время. Исправил стековую нотацию. Возникли ещё вопросы. 1. Перед IF на стеке отсутствует результат операции сравнения ( flag ). В IF входим со значением ior оставшимся от OPEN-FILE-SHARED Вопрос: это и будет, в данном случае, flag для IF? 2. Мне непонятно, что для THROW на стеке должно быть и что останется, на стеке когда THROW отработает? 3. Для чего вообще THROW в данном коде? [code]FOUND-FULLPATH R/W OPEN-FILE-SHARED ( --> fileid ior ) DUP ( fileid ior --> fileid ior ior ) \ перед IF на стеке отсутствует результат операции \ сравнения ( flag ). В IF входим со значением ior \ оставшимся от OPEN-FILE-SHARED \ Вопрос: это и будет, в данном случае, flag для IF? IF ( fileid ior ior --> fileid ior ) \ если ior <> 0 NIP ( fileid ior --> ior ) 32 ( ior --> ior 32 ) <> ( ior 32 --> flag ) ELSE ( fileid 0 0 --> fileid 0 ) \ если ior OPEN-FILE-SHARED = 0 \ т.е. файл нормально открылся DROP ( fileid 0 --> fileid ) CLOSE-FILE ( fileid --> ior ) \ А ниже мне непонятно, что для THROW \ на стеке должно быть и что останется, \ на стеке когда THROW отработает? THROW TRUE THEN[/code]
|
|
|
|
Добавлено: Пт мар 11, 2011 17:23 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
registration писал(а): DUP ( fileid ior --> fileid ior ior ) \ Вопрос: для чего дублировать ior? IF ( --> )( fileid ior ior --> fileid ior ior ) тут ошибочка в стековой нотации. Дублируется ior как раз для IF , который поглащает флаг, т.е. нижняя строчка должна выглядеть так: IF ( fileid ior ior --> fileid ior ) registration писал(а): \ Вопрос: Если далее мы ior удаляем? NIP ( fileid ior ior --> fileid ior ) нет, ошибка была выше, удаляется fid registration писал(а): 32 ( fileid ior --> fileid ior 32 ) <> ( fileid ior 32 --> fileid flag ) соответственно не так, а: <> ( ior 32 --> flag ) ну и так далее. Одна из идей Форта в том, что входящие параметры ВСЕГДА ПОГЛОЩАЮТСЯ (хотя ему следуют не всегда).
[quote="registration"]DUP ( fileid ior --> fileid ior ior ) \ Вопрос: для чего дублировать ior? IF ( --> )( fileid ior ior --> fileid ior ior )[/quote] тут ошибочка в стековой нотации. Дублируется ior как раз для IF , который поглащает флаг, т.е. нижняя строчка должна выглядеть так: IF ( fileid ior ior --> fileid ior ) [quote="registration"]\ Вопрос: Если далее мы ior удаляем? NIP ( fileid ior ior --> fileid ior )[/quote] нет, ошибка была выше, удаляется fid [quote="registration"]32 ( fileid ior --> fileid ior 32 ) <> ( fileid ior 32 --> fileid flag )[/quote] соответственно не так, а: <> ( ior 32 --> flag ) ну и так далее. Одна из идей Форта в том, что входящие параметры ВСЕГДА ПОГЛОЩАЮТСЯ (хотя ему следуют не всегда).
|
|
|
|
Добавлено: Чт мар 10, 2011 19:42 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
WingLion писал(а): Может, на стеке муча кусора остается после отработки циклов? Вполне возможно, только как проверить? Код любезно предоставленный Гостем вроде рабочий,ошибка не возникает (????), только непопонятно многое. Написал стековую нотацию для кода, чтоб понять происходящее на стеке Есть такие вопросы 1. для чего дублировать ior на вершине стека, если потом одну копию его удаляем? 2. Непонятно как выполняется CLOSE-FILE при таком состоянии стека на момент исполнения? Код: FOUND-FULLPATH R/W OPEN-FILE-SHARED ( --> fileid ior ) DUP ( fileid ior --> fileid ior ior ) \ Вопрос: для чего дублировать ior? IF ( --> )( fileid ior ior --> fileid ior ior ) \ если ior <> 0 \ Вопрос: Если далее мы ior удаляем? NIP ( fileid ior ior --> fileid ior ) 32 ( fileid ior --> fileid ior 32 ) <> ( fileid ior 32 --> fileid flag ) ELSE ( --> )( fileid 0 0 --> fileid 0 0 ) \ если ior OPEN-FILE-SHARED = 0 \ т.е. файл нормально открылся DROP ( fileid 0 0 --> fileid 0 ) \ А ниже мне непонятно, для CLOSE-FILE \ на стеке должно быть ( fileid --> \ а у нас ( fileid 0 --> CLOSE-FILE ( fileid 0 --> ???? ) \ дальше я стек отследить не смог THROW TRUE THEN
[quote="WingLion"]Может, на стеке муча кусора остается после отработки циклов?[/quote] Вполне возможно, только как проверить? Код любезно предоставленный [b]Гостем[/b] вроде рабочий,ошибка не возникает (????), только непопонятно многое.
Написал стековую нотацию для кода, чтоб понять происходящее на стеке Есть такие вопросы 1. для чего дублировать ior на вершине стека, если потом одну копию его удаляем? 2. Непонятно как выполняется CLOSE-FILE при таком состоянии стека на момент исполнения? [code]FOUND-FULLPATH R/W OPEN-FILE-SHARED ( --> fileid ior ) DUP ( fileid ior --> fileid ior ior ) \ Вопрос: для чего дублировать ior? IF ( --> )( fileid ior ior --> fileid ior ior ) \ если ior <> 0 \ Вопрос: Если далее мы ior удаляем? NIP ( fileid ior ior --> fileid ior ) 32 ( fileid ior --> fileid ior 32 ) <> ( fileid ior 32 --> fileid flag ) ELSE ( --> )( fileid 0 0 --> fileid 0 0 ) \ если ior OPEN-FILE-SHARED = 0 \ т.е. файл нормально открылся DROP ( fileid 0 0 --> fileid 0 ) \ А ниже мне непонятно, для CLOSE-FILE \ на стеке должно быть ( fileid --> \ а у нас ( fileid 0 --> CLOSE-FILE ( fileid 0 --> ???? ) \ дальше я стек отследить не смог THROW TRUE THEN[/code]
|
|
|
|
Добавлено: Чт мар 10, 2011 18:41 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
Может, на стеке муча кусора остается после отработки циклов?
Может, на стеке муча кусора остается после отработки циклов?
|
|
|
|
Добавлено: Ср мар 09, 2011 20:38 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
registration писал(а): возникает ошибка: 1772 File_Busy_Test2: Ошибка стека в Action: и файл держится уже кроном (возможно не срабатывает CLOSE-FILE DROP) Подскажите в чём проблема со стеком? GetLastError ненужен. Код: \ ... R/W OPEN-FILE-SHARED ( h|0 0|ior ) DUP IF NIP 32 <> ELSE DROP CLOSE-FILE THROW TRUE THEN UNTIL \ файл уже закрыт, если был открыт.
[quote="registration"]возникает ошибка: 1772 File_Busy_Test2: Ошибка стека в Action: и файл держится уже кроном (возможно не срабатывает CLOSE-FILE DROP) Подскажите в чём проблема со стеком?[/quote] GetLastError ненужен.
[code] \ ... R/W OPEN-FILE-SHARED ( h|0 0|ior ) DUP IF NIP 32 <> ELSE DROP CLOSE-FILE THROW TRUE THEN UNTIL \ файл уже закрыт, если был открыт. [/code]
|
|
|
|
Добавлено: Ср мар 09, 2011 17:39 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
Написал такой код: Код: #( File_Busy_Test2 AsLoggedUser \ NoActive SingleInstance WatchFile: "C:\dir1\dir2\dir3\????abc.dbf"
Action: FOR-FILES: "C:\dir1\dir2\dir3\????abc.dbf" BEGIN PAUSE: 200 FOUND-FULLPATH R/W OPEN-FILE-SHARED GetLastError 32 <> \ 32 -код ошибки ERROR_SHARING_VIOLATION UNTIL CLOSE-FILE DROP \ ." Закрыли файл" CR ." Всё вышли из цикла UNTIL" CR ;FOR-FILES ." Всё вышли из цикла FOR-FILES" CR )# Код вроде отрабатывает, в консоли вижу вывод строк выхода из циклов, но после этого возникает ошибка: 1772 File_Busy_Test2: Ошибка стека в Action: и файл держится уже кроном (возможно не срабатывает CLOSE-FILE DROP) Подскажите в чём проблема со стеком?
Написал такой код: [code]#( File_Busy_Test2 AsLoggedUser \ NoActive SingleInstance WatchFile: "C:\dir1\dir2\dir3\????abc.dbf"
Action: FOR-FILES: "C:\dir1\dir2\dir3\????abc.dbf" BEGIN PAUSE: 200 FOUND-FULLPATH R/W OPEN-FILE-SHARED GetLastError 32 <> \ 32 -код ошибки ERROR_SHARING_VIOLATION UNTIL CLOSE-FILE DROP \ ." Закрыли файл" CR ." Всё вышли из цикла UNTIL" CR ;FOR-FILES ." Всё вышли из цикла FOR-FILES" CR )#[/code] Код вроде отрабатывает, в консоли вижу вывод строк выхода из циклов, но после этого возникает ошибка: 1772 File_Busy_Test2: Ошибка стека в Action: и файл держится уже кроном (возможно не срабатывает CLOSE-FILE DROP) Подскажите в чём проблема со стеком?
|
|
|
|
Добавлено: Ср мар 09, 2011 12:59 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
Цитата: Файл формируеся на разделяемом сетевом ресурсе, произвольной машиной в сети Если файл формирует не "левая" программа, может заставить ее подать сигнальчик в нужное время нужному процессу (DDE, COM, и тп)
[quote]Файл формируеся на разделяемом сетевом ресурсе, произвольной машиной в сети[/quote] Если файл формирует не "левая" программа, может заставить ее подать сигнальчик в нужное время нужному процессу (DDE, COM, и тп)
|
|
|
|
Добавлено: Вс фев 27, 2011 12:13 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
В SPForth слово OPEN-FILE открывает файл в экслюзивном доступе ("монопольном", в таком режим файл может открыть только один процесс, остальным будет ошибка 32). Переименовать тоже не получится. Слово OPEN-FILE-SHARED -- открывает в разделяемом доступе (в таком режиме файл могут открыть несколько процессов). Файл, открытый этим словом, может быть переименован, перенесен, и даже удален (реально файл удалится после закрытия). Может быть полезно следующее слово из комплекта Eserv/3 Код: 1000 VALUE vFileWatchPeriod \ период проверки
: WAIT-FILE-EXCLUSIVE ( c-addr u tout -- ior ) \ ожидание монопольного доступа к файлу \ tout -- таймут ожидания в ms, если -1 то вечное ожидание \ если дождались, ior = 0 \ если timeout, ior = -1 { a u tout } a u FILE-EXIST 0= IF 2 EXIT THEN tout vFileWatchPeriod UMAX TO tout BEGIN a u R/O OPEN-FILE 0= IF CLOSE-FILE THROW 0 EXIT THEN DROP vFileWatchPeriod PAUSE tout -1 <> IF tout vFileWatchPeriod U< IF -1 EXIT THEN tout vFileWatchPeriod - TO tout THEN AGAIN ;
Это слово не подходит для конкурентного захвата файла (когда несколько процессов ждут один файл), т.к. оно "не захватывает" файл, он остается свободным и может быть захвачен другим процессом.
В SPForth слово OPEN-FILE открывает файл в экслюзивном доступе ("монопольном", в таком режим файл может открыть только один процесс, остальным будет ошибка 32). Переименовать тоже не получится.
Слово OPEN-FILE-SHARED -- открывает в разделяемом доступе (в таком режиме файл могут открыть несколько процессов). Файл, открытый этим словом, может быть переименован, перенесен, и даже удален (реально файл удалится после закрытия).
Может быть полезно следующее слово из комплекта Eserv/3 [code] 1000 VALUE vFileWatchPeriod \ период проверки
: WAIT-FILE-EXCLUSIVE ( c-addr u tout -- ior ) \ ожидание монопольного доступа к файлу \ tout -- таймут ожидания в ms, если -1 то вечное ожидание \ если дождались, ior = 0 \ если timeout, ior = -1 { a u tout } a u FILE-EXIST 0= IF 2 EXIT THEN tout vFileWatchPeriod UMAX TO tout BEGIN a u R/O OPEN-FILE 0= IF CLOSE-FILE THROW 0 EXIT THEN DROP vFileWatchPeriod PAUSE tout -1 <> IF tout vFileWatchPeriod U< IF -1 EXIT THEN tout vFileWatchPeriod - TO tout THEN AGAIN ; [/code] Это слово не подходит для конкурентного захвата файла (когда несколько процессов ждут один файл), т.к. оно "не захватывает" файл, он остается свободным и может быть захвачен другим процессом.
|
|
|
|
Добавлено: Сб фев 26, 2011 04:47 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как определить что "файл занят другим процессом"? |
|
|
Цитата: как захватить силами SPF монопольный доступ?
Может ошибаюсь, но похоже ни как, только доступом (обертками) к средствам ОС
[quote] как захватить силами SPF монопольный доступ? [/quote] Может ошибаюсь, но похоже ни как, только доступом (обертками) к средствам ОС
|
|
|
|
Добавлено: Пт фев 25, 2011 21:01 |
|
|
|
|