Что нового

[Баг] FileOpen, FileRead и т.д. не открывают занятый файл???

Manonegro

Новичок
Сообщения
24
Репутация
0
Ситуация такая: существует лог-файл одной программы, назовём её "Х". Раньше (до версии 3.3.4.0) файл превосходно открывался так:

$FileArray = StringSplit(FileRead($NameLogFile), @CR & @CRLF, 1)

Сейчас не работает. Файл спокойно открывается блокнотом. Если закрыть программу "Х", то всё работает. У меня одного так?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Попробуй указать в явном виде, что файл открывается только для чтения.

Код:
$hFile = FileOpen($NameLogFile, 0)
$Data = FileRead($hFile)
FileClose($hFile)
$FileArray = StringSplit($Data, @CR & @CRLF, 1)
 
Автор
M

Manonegro

Новичок
Сообщения
24
Репутация
0
Да нет же, пробовал. Уже на FileOpen (c любой цифрой) ошибка!!! На предыдущей версии всё было ОК. Программа "Х" - TeamViewer5.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 242
Репутация
2 344
А почему деление происходит по «@CR & @CRLF» (может в этом проблема), так вроде надёжнее:

Код:
$aFileArray = StringSplit(StringStripCR(FileRead($NameLogFile)), @LF)


Manonegro [?]
пробовал. Уже на FileOpen (c любой цифрой) ошибка
Какая?
 
Автор
M

Manonegro

Новичок
Сообщения
24
Репутация
0
А почему деление происходит по «@CR & @CRLF»?
Потому что строки делятся по 0d0d0a.

Полученный хэндл = -1.

Пробовал открыть через
Код:
$HandleLog = _WinAPI_CreateFile($NameLogFile, 2)

в результате $HandleLog = 0!!!
Похоже, по всем дисковым операциям баг... Попробовал на рабочем компе - то же самое. :(
 

snoitaleR

AutoIT Гуру
Сообщения
854
Репутация
223
Manonegro
У меня есть предположение: в новой версии программы TeamViewer файл отчета блокируется самой программой...
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
_WinAPI_CreateFile() не зависит от AutoIt, это функция WinAPI. Посмотри, что выдает _WinAPI_GetLastErrorMessage() сразу после вызова этой функции.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
Подтверждаю
WinXP SP3, AutoIt v3.3.4.0.
Файл открывается любым редактором. AutoIt не хочет
 
Автор
M

Manonegro

Новичок
Сообщения
24
Репутация
0
файл отчета блокируется самой программой...
Исключено. Версия не менялась. Откатывался на AutoIt! 3.3.2.0 - всё работает. Файл отчета открывается в любом редакторе спокойно.

Посмотри, что выдает _WinAPI_GetLastErrorMessage()
Выдаёт "Операция успешно завершена". :blink:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Если хэндл ревен 0, то операция не может быть успешно завершена. _WinAPI_GetLastErrorMessage() нужно вызывать сразу после _WinAPI_CreateFile().
 
Автор
M

Manonegro

Новичок
Сообщения
24
Репутация
0
Код:
$HandleLog = _WinAPI_CreateFile($NameLogFile, 2)
MsgBox(4096, "Ошибка", $HandleLog)
MsgBox(4096, "Ошибка", _WinAPI_GetLastErrorMessage())


Первое сообщение - "0", второе - "Операция успешно завершена". Понятно, что не может быть, но факт...


Добавлено:
Сообщение автоматически объединено:

Извиняюсь, переписал код
Код:
$HandleLog = _WinAPI_CreateFile($NameLogFile, 2)
$Temp = _WinAPI_GetLastErrorMessage()
MsgBox(4096, "Ошибка", $HandleLog)
MsgBox(4096, "Ошибка", $Temp)


Первое сообщение - "0", второе - "Процесс не может получить доступ к файлу, т.к. файл занят другим процессом".
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Я же сказал, сразу после _WinAPI_CreateFile().

Код:
$HandleLog = _WinAPI_CreateFile($NameLogFile, 2)
MsgBox(4096, "Ошибка", _WinAPI_GetLastErrorMessage())
MsgBox(4096, "Ошибка", $HandleLog)




Добавлено:
Сообщение автоматически объединено:

Manonegro [?]
"Процесс не может получить доступ к файлу, т.к. файл занят другим процессом"
Вот и ответ на твой вопрос.

Попробуй еще так:

Код:
_WinAPI_CreateFile($NameLogFile, 2, 2)
 
Автор
M

Manonegro

Новичок
Сообщения
24
Репутация
0
Вот и ответ на твой вопрос.
Это не ответ, а подтверждение, что в 3.3.2.0 всё работает.

Попробуй еще так
Всяко пробовал:

Код:
_WinAPI_CreateFile($NameLogFile, 2)
_WinAPI_CreateFile($NameLogFile, 2,2)
_WinAPI_CreateFile($NameLogFile, 2,2,2)


Выдают один и тот же результат... Вернее, не выдают ничего ;D
 

snoitaleR

AutoIT Гуру
Сообщения
854
Репутация
223
Manonegro
У меня второе предположение: в версии AUTOIT.3.3.4.0 корректнее обрабатываются заблокированные файлы или это баг...
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
snoitaleR [?]
в версии AUTOIT.3.3.4.0 корректнее обрабатываются заблокированные файлы
в чем заключается корректность? в том, что AutoIt не может открыть файл для чтения, когда любой другой редактор может открывать даже на запись? ;D
 

snoitaleR

AutoIT Гуру
Сообщения
854
Репутация
223
Kaster
В моем понимании корректность - это создание условий, при которых вероятность повреждения информации в файле минимальна...
Может быть, AUTOIT получил информацию о том, что файл уже открыт для записи, и поэтому, чтобы снизить вероятность повреждения информации запрещает некоторые файловые операции над этим файлом...
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
snoitaleR
в том-то и дело, что сам TeamViewer не ограничивает доступ к файлу никоим образом. в этом можно убедиться открыв файл другим текстовым редактором. я даже смог записать в этот файл что-то и сохранить. никаких предупреждений и прочего. все остальное - это уже AutoIt. уж что он там себе думает, пока загадка.
да и потом, открытие файла для чтения никоим образом не влияет на вероятность повреждения информации.
 

snoitaleR

AutoIT Гуру
Сообщения
854
Репутация
223
Kaster
Тогда можно смело оформлять баг-репорт... :smile:
 
Автор
M

Manonegro

Новичок
Сообщения
24
Репутация
0
Попробовал на старом-добром ассемблере:

Код:
	xor edi,edi
	invoke CreateFile,offset FileName,GENERIC_READ,FILE_SHARE_READ + FILE_SHARE_WRITE,edi,OPEN_EXISTING,edi,edi
	mov esi,eax
;Получили хэндл файла
	invoke GetFileSize,eax,edi
	mov ecx,eax
;Получили размер файла
	invoke CreateFileMapping,esi,edi,PAGE_READONLY,edi,edi,edi
	mov ebx,eax
;Получили hMap файла
	invoke MapViewOfFile,eax,FILE_MAP_READ,edi,edi,edi
	xchg esi,eax
;Получили адрес файла в памяти
Все пункты завершились удачно.
На AutoIt! хэндл файла удалось получить так:

Код:
$HandleLog = _WinAPI_CreateFile($NameLogFile, 2, 2, 6)


но его нельзя использовать в FileRead(), только в WinAPI-функциях...
Короче, откатился пока на 3.3.2.0. А жаль... :(
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4 020
Репутация
622
Получилось вытащить содержимое файла через такой финт ушами
Код:
#include <WinAPI.au3>
Global $sFile, $hFile, $sText, $nBytes, $tBuffer
$f = 'C:\Program Files\TeamViewer\Version5\TeamViewer5_Logfile.log'
$FileSize = FileGetSize($f)
$tBuffer = DllStructCreate("byte[" & $FileSize & "]")
$hFile = _WinAPI_CreateFile($f, 2, 2, 6)
;_WinAPI_SetFilePointer($hFile, 3)
_WinAPI_ReadFile($hFile, DllStructGetPtr($tBuffer), $FileSize, $nBytes)
;_WinAPI_CloseHandle($hFile)
$sText = BinaryToString(DllStructGetData($tBuffer, 1))
MsgBox(0, '', $sText)
 
Верх