Что нового

Использование UDF мониторинга за файлами

MnM

Post-Hardcore
Сообщения
679
Репутация
90
Здравствуйте. У меня просьба, помогите разобраться в функциях сторонней UDF FileSystemMonitor.au3 читал про неё http://www.autoitscript.com/forum/topic/113560-filesystemmonitor-udf/ но не понял действие функций, так как в примерах в основном написаны собственные(автора) функции и не совсем понятна логика.
 

AZJIO

Меценат
Меценат
Сообщения
2,903
Репутация
1,200
MnM
Можно было в предыдущей теме продолжить.
Вот упрощённый вариант, который я делал для слежения за файлом:

Код:
; Использовал UDF по ссылке, модернизировал для себя (AZJIO)
; http://www.autoitscript.com/forum/index.php?showtopic=113560&st=0


Global $pDirEvents
Global $hDir
Global $pOverLapped
Global $tFNI
Global $pBuffer
Global $Filename
Global $iBufferSize
Global $tOverLapped
Global $tBuffer
Global $tDirEvents
Global $iDirEvents
Global $hEvent
Global $FileMon='проверочный файл.ini'
If Not FileExists($FileMon) Then
	MsgBox(0, 'Сообщение', 'Не найден файл')
	Exit
EndIf

; тело скрипта
;!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i
$Tr1=0
_FileSysMonSetup()
While 1
	$Filename=_FileSysMonDirEventHandler()
	If $Filename=$FileMon Then
		$Tr1+=1
		If $Tr1=2 Then
			MsgBox(0, 'Сообщение', 'Файл изменён')
			$Tr1=0
		EndIf
		$Filename=''
	EndIf
	Sleep(1000)
WEnd

Func _FileSysMonActionEvent($event_value)
	;Двойное сообщение - до и после изменения, напримеро пеерименование.
	MsgBox(0, 'Message', $event_value)
EndFunc   ;==>_FileSysMonActionEvent
;!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i!i

Func _FileSysMonSetup($sdir = @ScriptDir)
		$tBuffer = DllStructCreate("byte[4096]")
		$pBuffer = DllStructGetPtr($tBuffer)
		$iBufferSize = DllStructGetSize($tBuffer)
		$tFNI = 0
		$hDir = DllCall("kernel32.dll", "hwnd", "CreateFile", "Str", $sdir, "Int", 0x1, "Int", BitOR(0x1, 0x4, 0x2), "ptr", 0, "int", 0x3, "int", BitOR(0x2000000, 0x40000000), "int", 0)
		$hDir = $hDir[0]
		$tReadLen = DllStructCreate("dword ReadLen")
		$tOverLapped = DllStructCreate("Uint OL1;Uint OL2; Uint OL3; Uint OL4; hwnd OL5")
		For $i = 1 To 5
			DllStructSetData($tOverLapped, $i, 0)
		Next
		$pOverLapped = DllStructGetPtr($tOverLapped)
		$iOverLappedSize = DllStructGetSize($tOverLapped)
		$tDirEvents = DllStructCreate("hwnd DirEvents")
		$pDirEvents = DllStructGetPtr($tDirEvents)
		$iDirEvents = DllStructGetSize($tDirEvents)
		$hEvent = DllCall("kernel32.dll", "hwnd", "CreateEvent", "UInt", 0, "Int", True, "Int", False, "UInt", 0)
		DllStructSetData($tOverLapped, 5, $hEvent[0])
		DllStructSetData($tDirEvents, 1, $hEvent[0])
		$ret = DllCall("kernel32.dll", "Int", "ReadDirectoryChangesW", "hwnd", $hDir, "ptr", $pBuffer, "dword", $iBufferSize, "int", False, "dword", BitOR(0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x100), "Uint", 0, "Uint", $pOverLapped, "Uint", 0)
		$Filename = ""
	Return True
EndFunc   ;==>_FileSysMonSetup

Func _FileSysMonDirEventHandler()
	Local $r, $iOffset, $nReadLen, $tStr, $iNext, $ff, $ret
	$r = DllCall("User32.dll", "dword", "MsgWaitForMultipleObjectsEx", "dword", 1, "ptr", $pDirEvents, "dword", 100, "dword", 0x4FF, "dword", 0x6)
	If $r[0] = 0 Then
		$iOffset = 0
		$nReadLen = 0
		$d = 0
		DllCall("kernel32.dll", "Uint", "GetOverlappedResult", "hWnd", $hDir, "Uint", $pOverLapped, "UInt*", $nReadLen, "Int", True)
		While 1
			$tFNI = DllStructCreate("dword Next;dword Action;dword FilenameLen", $pBuffer + $iOffset)
			$tStr = DllStructCreate("wchar[" & DllStructGetData($tFNI, "FilenameLen") / 2 & "]", $pBuffer + $iOffset + 12)
			$Filename = DllStructGetData($tStr, 1)
			$iNext = DllStructGetData($tFNI, "Next")
			If $iNext = 0 Then ExitLoop
			$iOffset += $iNext
		WEnd
		$ff = DllStructGetData($tOverLapped, 5)
		DllCall("kernel32.dll", "Uint", "ResetEvent", "UInt", $ff)
		$ret = DllCall("kernel32.dll", "Int", "ReadDirectoryChangesW", "hwnd", $hDir, "ptr", $pBuffer, "dword", $iBufferSize, "int", False, "dword", BitOR(0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x100), "Uint", 0, "Uint", $pOverLapped, "Uint", 0)
	EndIf
	Return $Filename
EndFunc   ;==>_FileSysMonDirEventHandler


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