Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   [решено] Контроль изменения файлов (http://forum.oszone.net/showthread.php?t=245201)

support23 22-10-2012 11:44 2010055

Контроль изменения файлов
 
Доброго дня!
Есть задача: Необходимо контролировать файлы (расширения разные - dll, xml, ini и т.д.) в заданной папке, на предмет их удаления, добавления новых, изменения существующих. И отражать это в лог файле (дата, время, какие были изменения - например удален файл name.exe, изменен файл name.ini)
Как это можно реализовать?

Iska 22-10-2012 14:06 2010139

support23, файлов только в самой папке? Без учёта вложенных в неё папок?

support23 22-10-2012 15:05 2010176

Цитата:

Цитата Iska
support23, файлов только в самой папке? Без учёта вложенных в неё папок? »

Да, вложенных папок нет.

266903582 22-10-2012 18:31 2010295

Получаем список файлов (_FileListToArray,FileFindFirstFile,FileFindNextFile)
Пишем его в файл (например ini)
С нужной периодичностью получаем текущий список и для каждого файла сравниваем со старым списком. Так отсеиваем появление/исчезнвение файлов.
Для каждого файла считаем контрольную сумму (_CRC32()), пишем ее туда-же в ini файл в раздел с именем данного файла. Так сможем отслеживать реальные изменения файлов.
Для отслеживания дат изменения используем информацию из атрибутов (FileGetAttrib (),FileGetTime ()), пишем ее рядом с контрольной суммой.
Определять конкретные изменения в файлах уже сложнее, тут уже от типов файлов зависит...

Iska 23-10-2012 02:29 2010517

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


AZJIO 23-10-2012 05:58 2010535

FileSystemMonitor
http://autoit-script.ru/index.php/topic,6426.0.html - Если поискать найдётся ещё несколько тем.

support23 23-10-2012 15:28 2010748

Цитата:

Цитата Iska
support23, пробуйте: »

Спасибо за предложенный вариант, есть несколько недостатков - не понимает русские имена файлов, при переименовании файла в папке, завершает работу с ошибкой, и желательно чтобы был лог

Iska 23-10-2012 16:11 2010766

support23, что означает:
Цитата:

Цитата support23
не понимает русские имена файлов »

?

Это:
Цитата:

Цитата support23
при переименовании файла в папке, завершает работу с ошибкой »

посмотрю.

Цитата:

Цитата support23
и желательно чтобы был лог »

Перенаправьте вывод в файл.

support23 23-10-2012 16:24 2010773

1. файл checkdir - копия (2).exe при выполнении в консоли отображается как checkdir - Є®ЇЁп (2).exe ( | Create: [e:\test\checkdir - Є®ЇЁп (2).xml])
2. спасибо
3. для этого недостаточно знаний, к сожалению

Iska 24-10-2012 01:18 2011077

Цитата:

Цитата support23
1. файл checkdir - копия (2).exe при выполнении в консоли отображается как checkdir - Є®ЇЁп (2).exe ( | Create: [e:\test\checkdir - Є®ЇЁп (2).xml]) »



Попробуйте использовать TrueType-шрифт для окна консоли.

Цитата:

Цитата support23
при переименовании файла в папке, завершает работу с ошибкой, »

Переименовываю, но ошибка не воспроизводится:



Цитата:

Цитата support23
Цитата:

Цитата Iska
Перенаправьте вывод в файл. »

3. для этого недостаточно знаний, к сожалению »

Код:

bla-bla-bla.exe >Log.txt

support23 26-10-2012 09:10 2012405

Есть несколько файлов в каталоге
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


Iska 26-10-2012 18:48 2012795

support23, скомпилируйте скрипт и исполняйте скомпилированный файл.

support23 29-10-2012 12:54 2014236

Вложений: 1
скомпилировал файл, запустил, при переименовании уже существующего файла в папке получаю такую ошибку:

http://forum.oszone.net/attachment.p...1&d=1351500780

Iska 29-10-2012 22:31 2014654

support23, кажется, я понял: у Вас уже существуют файлы в каталоге перед запуском скрипта. И один из них, после запуска скрипта, Вы пытаетесь удалить. Так?

support23 30-10-2012 08:53 2014856

Цитата:

Цитата Iska
support23, кажется, я понял: у Вас уже существуют файлы в каталоге перед запуском скрипта. И один из них, после запуска скрипта, Вы пытаетесь удалить. Так? »

да, всё верно!

Iska 30-10-2012 09:25 2014869

Надо будет при запуске заполнять словарь существующими файлами. Пробуйте:
читать дальше »
Код:

#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 2015623

Благодарю! работает отлично!


Время: 19:28.

Время: 19:28.
© OSzone.net 2001-