Что нового

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

Manonegro

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

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

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

Yashied

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

Код:
$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,671
Репутация
2,481
А почему деление происходит по «@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 Гуру
Сообщения
855
Репутация
223
Manonegro
У меня есть предположение: в новой версии программы TeamViewer файл отчета блокируется самой программой...
 

Yashied

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

kaster

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

Manonegro

Новичок
Сообщения
24
Репутация
0
файл отчета блокируется самой программой...

Исключено. Версия не менялась. Откатывался на AutoIt! 3.3.2.0 - всё работает. Файл отчета открывается в любом редакторе спокойно.

Посмотри, что выдает _WinAPI_GetLastErrorMessage()

Выдаёт "Операция успешно завершена". :blink:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Если хэндл ревен 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,724
Я же сказал, сразу после _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 Гуру
Сообщения
855
Репутация
223
Manonegro
У меня второе предположение: в версии AUTOIT.3.3.4.0 корректнее обрабатываются заблокированные файлы или это баг...
 

kaster

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

snoitaleR

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

kaster

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

snoitaleR

AutoIT Гуру
Сообщения
855
Репутация
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
Репутация
626
Получилось вытащить содержимое файла через такой финт ушами
Код:
#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)
 
Верх