Показать полную графическую версию : [решено] Контроль изменения файлов
support23
22-10-2012, 11:44
Доброго дня!
Есть задача: Необходимо контролировать файлы (расширения разные - dll, xml, ini и т.д.) в заданной папке, на предмет их удаления, добавления новых, изменения существующих. И отражать это в лог файле (дата, время, какие были изменения - например удален файл name.exe, изменен файл name.ini)
Как это можно реализовать?
support23, файлов только в самой папке? Без учёта вложенных в неё папок?
support23
22-10-2012, 15:05
support23, файлов только в самой папке? Без учёта вложенных в неё папок? »
Да, вложенных папок нет.
266903582
22-10-2012, 18:31
Получаем список файлов (_FileListToArray,FileFindFirstFile,FileFindNextFile)
Пишем его в файл (например ini)
С нужной периодичностью получаем текущий список и для каждого файла сравниваем со старым списком. Так отсеиваем появление/исчезнвение файлов.
Для каждого файла считаем контрольную сумму (_CRC32()), пишем ее туда-же в ini файл в раздел с именем данного файла. Так сможем отслеживать реальные изменения файлов.
Для отслеживания дат изменения используем информацию из атрибутов (FileGetAttrib (),FileGetTime ()), пишем ее рядом с контрольной суммой.
Определять конкретные изменения в файлах уже сложнее, тут уже от типов файлов зависит...
support23, пробуйте:
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Change2CUI=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <file.au3>
#Include <Date.au3>
#Include <WinAPI.au3>
#Include <Crypt.au3>
AutoItSetOption("MustDeclareVars", 1)
Local $sFolder = "e:\Песочница\0190"
Local $sComputer = "."
Local $oSWbemLocator = ObjCreate("WbemScripting.SWbemLocator")
Local $oSWbemServicesEx = $oSWbemLocator.ConnectServer($sComputer, "root\cimv2")
Local $oSWbemSink = ObjCreate("WbemScripting.SWbemSink")
Local $oSink = ObjEvent($oSWbemSink, "Sink_")
Local $aSplitPath, $sDrive, $sDir, $sFileName, $sExtension
Local $dtNow, $sNow
Local $sMD5
Local $oDictionary = ObjCreate("Scripting.Dictionary")
_PathSplit($sFolder & "\", $sDrive, $sDir, $sFileName, $sExtension)
$oSWbemServicesEx.ExecNotificationQueryAsync($oSWbemSink, _
"SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE " & _
"TargetInstance ISA 'CIM_DataFile' AND " & _
"TargetInstance.Drive = '" & $sDrive & "' AND " & _
"TargetInstance.Path = '" & StringReplace($sDir, "\", "\\") & "'" _
)
_Crypt_Startup()
Do
Sleep(100)
Until(False)
_Crypt_Shutdown()
$oDictionary.RemoveAll
$oDictionary = 0
$oSink = 0
$oSWbemSink = 0
$oSWbemServicesEx = 0
$oSWbemLocator = 0
Exit(0)
Func Sink_OnObjectReady($oSWbemObjectEx, $oSWbemAsyncContext)
With $oSWbemObjectEx
$dtNow = _Date_Time_GetLocalTime()
$sNow = _Date_Time_SystemTimeToDateTimeStr($dtNow, 1)
Select
Case .Path_.Class = "__InstanceCreationEvent"
$sMD5 = _Crypt_HashFile(.TargetInstance.Name, $CALG_MD5)
$oDictionary.Add(.TargetInstance.Name, $sMD5)
ConsoleWrite($sNow & _WinAPI_WideCharToMultiByte(" | | Create: [" & .TargetInstance.Name, 1) & "]" & @CRLF)
Case .Path_.Class = "__InstanceModificationEvent"
$sMD5 = _Crypt_HashFile(.TargetInstance.Name, $CALG_MD5)
If $oDictionary.Exists(.TargetInstance.Name) Then
If $oDictionary.Item(.TargetInstance.Name) <> $sMD5 Then
$oDictionary.Item(.TargetInstance.Name) = $sMD5
ConsoleWrite($sNow & _WinAPI_WideCharToMultiByte(" | | Modify: [" & .TargetInstance.Name, 1) & "]" & @CRLF)
EndIf
Else
$oDictionary.Add(.TargetInstance.Name, $sMD5)
ConsoleWrite($sNow & _WinAPI_WideCharToMultiByte(" | ± | Modify: [" & .TargetInstance.Name, 1) & "]" & @CRLF)
EndIf
Case .Path_.Class = "__InstanceDeletionEvent"
$oDictionary.Remove(.TargetInstance.Name)
ConsoleWrite($sNow & _WinAPI_WideCharToMultiByte(" | | Delete: [" & .TargetInstance.Name, 1) & "]" & @CRLF)
Case Else
; Nothing to do
EndSelect
EndWith
EndFunc
FileSystemMonitor (http://www.autoitscript.com/forum/index.php?showtopic=113560&st=0)
http://autoit-script.ru/index.php/topic,6426.0.html - Если поискать найдётся ещё несколько тем.
support23
23-10-2012, 15:28
support23, пробуйте: »
Спасибо за предложенный вариант, есть несколько недостатков - не понимает русские имена файлов, при переименовании файла в папке, завершает работу с ошибкой, и желательно чтобы был лог
support23, что означает:
не понимает русские имена файлов »
?
Это:
при переименовании файла в папке, завершает работу с ошибкой »
посмотрю.
и желательно чтобы был лог »
Перенаправьте вывод в файл.
support23
23-10-2012, 16:24
1. файл checkdir - копия (2).exe при выполнении в консоли отображается как checkdir - Є®ЇЁп (2).exe ( | Create: [e:\test\checkdir - Є®ЇЁп (2).xml])
2. спасибо
3. для этого недостаточно знаний, к сожалению
1. файл checkdir - копия (2).exe при выполнении в консоли отображается как checkdir - Є®ЇЁп (2).exe ( | Create: [e:\test\checkdir - Є®ЇЁп (2).xml]) »
http://img703.imageshack.us/img703/9012/image00020121024011007.png
Попробуйте использовать TrueType-шрифт для окна консоли.
при переименовании файла в папке, завершает работу с ошибкой, »
Переименовываю, но ошибка не воспроизводится:
http://img525.imageshack.us/img525/6326/image00020121024011348.png
Перенаправьте вывод в файл. »
3. для этого недостаточно знаний, к сожалению »
bla-bla-bla.exe >Log.txt
support23
26-10-2012, 09:10
Есть несколько файлов в каталоге
E:\Open
Скрипт запускаю на выполнение из Autoit (F5)
при удалении файла из каталога E:\Open получаю ошибку
>"C:\Program Files\AutoIt3\SciTE\..\autoit3.exe" /ErrorStdOut "E:\Test\mont.au3"
E:\Test\mont.au3 (79) : ==> The requested action with this object has failed.:
$oDictionary.Remove(.TargetInstance.Name)
$oDictionary.Remove(.TargetInstance.Name)^ ERROR
support23, скомпилируйте скрипт и исполняйте скомпилированный файл.
support23
29-10-2012, 12:54
скомпилировал файл, запустил, при переименовании уже существующего файла в папке получаю такую ошибку:
http://forum.oszone.net/attachment.php?attachmentid=89234&stc=1&d=1351500780
support23, кажется, я понял: у Вас уже существуют файлы в каталоге перед запуском скрипта. И один из них, после запуска скрипта, Вы пытаетесь удалить. Так?
support23
30-10-2012, 08:53
support23, кажется, я понял: у Вас уже существуют файлы в каталоге перед запуском скрипта. И один из них, после запуска скрипта, Вы пытаетесь удалить. Так? »
да, всё верно!
Надо будет при запуске заполнять словарь существующими файлами. Пробуйте:
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Change2CUI=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <file.au3>
#Include <Date.au3>
#Include <WinAPI.au3>
#Include <Crypt.au3>
AutoItSetOption("MustDeclareVars", 1)
Local $sFolder = "e:\Песочница\0190\0001"
Local $sComputer = "."
Local $oSWbemLocator = ObjCreate("WbemScripting.SWbemLocator")
Local $oSWbemServicesEx = $oSWbemLocator.ConnectServer($sComputer, "root\cimv2")
Local $oSWbemObjectEx
Local $oSWbemSink = ObjCreate("WbemScripting.SWbemSink")
Local $oSink = ObjEvent($oSWbemSink, "Sink_")
Local $aSplitPath, $sDrive, $sDir, $sFileName, $sExtension
Local $dtNow, $sNow
Local $sMD5
Local $oDictionary = ObjCreate("Scripting.Dictionary")
_PathSplit($sFolder & "\", $sDrive, $sDir, $sFileName, $sExtension)
$dtNow = _Date_Time_GetLocalTime()
$sNow = _Date_Time_SystemTimeToDateTimeStr($dtNow, 1)
For $oSWbemObjectEx In $oSWbemServicesEx.ExecQuery( _
"SELECT * FROM CIM_DataFile WHERE " & _
"Drive = '" & $sDrive & "' AND " & _
"Path = '" & StringReplace($sDir, "\", "\\") & "'" _
)
$sMD5 = _Crypt_HashFile($oSWbemObjectEx.Name, $CALG_MD5)
$oDictionary.Add($oSWbemObjectEx.Name, $sMD5)
ConsoleWrite($sNow & _WinAPI_WideCharToMultiByte(" | | Present: [" & $oSWbemObjectEx.Name, 1) & "]" & @CRLF)
Next
$oSWbemServicesEx.ExecNotificationQueryAsync($oSWbemSink, _
"SELECT * FROM __InstanceOperationEvent WITHIN 1 WHERE " & _
"TargetInstance ISA 'CIM_DataFile' AND " & _
"TargetInstance.Drive = '" & $sDrive & "' AND " & _
"TargetInstance.Path = '" & StringReplace($sDir, "\", "\\") & "'" _
)
_Crypt_Startup()
Do
Sleep(100)
Until(False)
_Crypt_Shutdown()
$oDictionary.RemoveAll
$oDictionary = 0
$oSink = 0
$oSWbemSink = 0
$oSWbemServicesEx = 0
$oSWbemLocator = 0
Exit(0)
Func Sink_OnObjectReady($oSWbemObjectEx, $oSWbemAsyncContext)
With $oSWbemObjectEx
$dtNow = _Date_Time_GetLocalTime()
$sNow = _Date_Time_SystemTimeToDateTimeStr($dtNow, 1)
Select
Case .Path_.Class = "__InstanceCreationEvent"
$sMD5 = _Crypt_HashFile(.TargetInstance.Name, $CALG_MD5)
$oDictionary.Add(.TargetInstance.Name, $sMD5)
ConsoleWrite($sNow & _WinAPI_WideCharToMultiByte(" | | Create: [" & .TargetInstance.Name, 1) & "]" & @CRLF)
Case .Path_.Class = "__InstanceModificationEvent"
$sMD5 = _Crypt_HashFile(.TargetInstance.Name, $CALG_MD5)
If $oDictionary.Exists(.TargetInstance.Name) Then
If $oDictionary.Item(.TargetInstance.Name) <> $sMD5 Then
$oDictionary.Item(.TargetInstance.Name) = $sMD5
ConsoleWrite($sNow & _WinAPI_WideCharToMultiByte(" | | Modify: [" & .TargetInstance.Name, 1) & "]" & @CRLF)
EndIf
Else
$oDictionary.Add(.TargetInstance.Name, $sMD5)
ConsoleWrite($sNow & _WinAPI_WideCharToMultiByte(" | ± | Modify: [" & .TargetInstance.Name, 1) & "]" & @CRLF)
EndIf
Case .Path_.Class = "__InstanceDeletionEvent"
$oDictionary.Remove(.TargetInstance.Name)
ConsoleWrite($sNow & _WinAPI_WideCharToMultiByte(" | | Delete: [" & .TargetInstance.Name, 1) & "]" & @CRLF)
Case Else
; Nothing to do
EndSelect
EndWith
EndFunc
support23
31-10-2012, 09:36
Благодарю! работает отлично!
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.