Что нового

Как использовать структуру WIN32_FIND_DATA ffd из MSDN в Autoit

assch

Новичок
Сообщения
166
Репутация
4
В MSDN есть ссылка http://msdn.microsoft.com/en-us/library/aa365200(v=VS.85).aspx
При помощи функций:
FindFirstFile
FindNextFile
Собирается информация о файлах в директории при помощи структуры WIN32_FIND_DATA ffd
А на Autoit такую конструкцию сделать можно? Не именно такую же как на ссылке а просто как то
прикрутить структуру WIN32_FIND_DATA ffd в эти функции для сбора информации о файлах
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Здесь под спойлером функция на C которая делает снимок директории. Эту функцию я вытащил из программы regshot 1.8.2 которая распространяется бесплатно, и с исходным кодом. Здесь видно что при помощи структуры WIN32_FIND_DATA ffd функция не только выводит список файлов, но и как я понимаю запоминает показатели с этих файлов, в частности последней модификации файла. По этому при повторном снимке и последующем сравнении она (regshot 1.8.2) выводит список не только добавленных и удалённых файлов но и файлов которые подверглись модификации проще говоря изменённых файлов Я собственно говоря и пытаюсь перетащить эти функции (regshot 1.8.2) на язык своего любомого Autoit Я знаю что есть функция FileGetTime но каждый раз вызывать эту функцию для каждого из файлов это наверно сильно увеличит время ,а в этой функции мне кажется вся информация идёт из структуры WIN32_FIND_DATA ffd Хотя могу и ошибатся.
//------------------------------------------------------------
// File Shot Engine
//------------------------------------------------------------
VOID GetFilesSnap(LPFILECONTENT lpFatherFile)
{
LPSTR lpFilename,lpTemp;
HANDLE filehandle;
WIN32_FIND_DATA finddata;
LPFILECONTENT lpFileContent,lpFileContentTemp;

lpTemp=GetWholeFileName(lpFatherFile);

{
lpFilename=MYALLOC(strlen(lpTemp)+5);
strcpy(lpFilename,lpTemp);
}
strcat(lpFilename,"\\*.*");

MYFREE(lpTemp);

filehandle=FindFirstFile(lpFilename,&finddata);
MYFREE(lpFilename);
if(filehandle==INVALID_HANDLE_VALUE)
return;

lpTemp=finddata.cFileName;

lpFileContent=MYALLOC0(sizeof(FILECONTENT));
lpFileContent->lpfilename=MYALLOC0(strlen(finddata.cFileName)+1); //must add one!
strcpy(lpFileContent->lpfilename,finddata.cFileName);
lpFileContent->writetimelow=finddata.ftLastWriteTime.dwLowDateTime;
lpFileContent->writetimehigh=finddata.ftLastWriteTime.dwHighDateTime;
lpFileContent->filesizelow=finddata.nFileSizeLow;
lpFileContent->filesizehigh=finddata.nFileSizeHigh;
lpFileContent->fileattr=finddata.dwFileAttributes;
lpFileContent->lpfatherfile=lpFatherFile;
lpFatherFile->lpfirstsubfile=lpFileContent;
lpFileContentTemp=lpFileContent;

if(ISDIR(lpFileContent->fileattr))
{
if( *(unsigned short *)lpTemp!=0x002E && !( *(unsigned short *)lpTemp==0x2E2E && *(lpTemp+2)==0x00 ) //1.8.2
&&!IsInSkipList(lpFileContent->lpfilename,lpSnapFiles)) //tfx
{

nGettingDir++;
GetFilesSnap(lpFileContent);
}
}
else
{
nGettingFile++;
}


for (;FindNextFile(filehandle,&finddata)!=FALSE;)
{
lpFileContent=MYALLOC0(sizeof(FILECONTENT));
lpFileContent->lpfilename=MYALLOC0(strlen(finddata.cFileName)+1);
strcpy(lpFileContent->lpfilename,finddata.cFileName);
lpFileContent->writetimelow=finddata.ftLastWriteTime.dwLowDateTime;
lpFileContent->writetimehigh=finddata.ftLastWriteTime.dwHighDateTime;
lpFileContent->filesizelow=finddata.nFileSizeLow;
lpFileContent->filesizehigh=finddata.nFileSizeHigh;
lpFileContent->fileattr=finddata.dwFileAttributes;
lpFileContent->lpfatherfile=lpFatherFile;
lpFileContentTemp->lpbrotherfile=lpFileContent;
lpFileContentTemp=lpFileContent;

if(ISDIR(lpFileContent->fileattr))
{
if( *(unsigned short *)lpTemp!=0x002E && !( *(unsigned short *)lpTemp==0x2E2E && *(lpTemp+2)==0x00 ) //1.8.2
&&!IsInSkipList(lpFileContent->lpfilename,lpSnapFiles)) //tfx
{
nGettingDir++;
GetFilesSnap(lpFileContent);
}
}
else
{
nGettingFile++;
}

}
FindClose(filehandle);

nGettingTime=GetTickCount();
if ((nGettingTime-nBASETIME1)>REFRESHINTERVAL)
{
UpdateCounters(lan_dir,lan_file,nGettingDir,nGettingFile);
}

return ;
}
 

kaster

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

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
assch, можно конечно это написать и через DllCall(), но с родными функциями AutoIt, это будет все равно быстрее (уж по крайней мере не медленнее). Не заморачивайся с этим и используй те преимущества AutoIt, из-за которых, он является "твоим любимым".
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
То есть попробывать прикрутить функцию FileGetTime
И вы думаете это будет работать по крайне мере не медленнее чем этот код на С ?
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
assch сказал(а):
И вы думаете это будет работать по крайне мере не медленнее чем этот код на С?
Это будет работать быстрее, чем на AutoIt с использованием DllCall(). А без DllCall() и DllStruct... здесь ну никак не обойтись. На C/C++ теоретически должно быть быстрее, но не намного (на чуть-чуть). Все зависит от смамого алгоритма.
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
То есть без DllCall() и DllStruct... здесь ну никак не обойтись?
Да, жалко что выстроить такую конструкцию с использованием DllCall() и DllStruct для меня будет проблематично.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
assch, что ты так вцепился в эту WIN32_FIND_DATA? Вот простой пример на "чистом" WinAPI:

Код:
#Include <StructureConstants.au3>

Global Const $sPath = @SystemDir
Global Const $sMask = '*'

$Timer = TimerInit()

$tWFD = DllStructCreate($tagWIN32_FIND_DATA)
$pWFD = DllStructGetPtr($tWFD)
$pFT = DllStructGetPtr($tWFD, 'ftLastWriteTime')
$tST = DllStructCreate($tagSYSTEMTIME)
$pST = DllStructGetPtr($tST)
$tLT = DllStructCreate($tagFILETIME)
$pLT = DllStructGetPtr($tLT)

$hFind = DllCall('kernel32.dll', 'ptr', 'FindFirstFileW', 'wstr', $sPath & '\' & $sMask, 'ptr', $pWFD)
If (@error) Or ($hFind[0] = -1) Then
	Exit
EndIf
Do
	$sFile = DllStructGetData($tWFD, 'cFileName')
	If StringLeft($sFile, 1) <> '.' Then
		DllCall('kernel32.dll', 'bool', 'FileTimeToLocalFileTime', 'ptr', $pFT, 'ptr', $pLT)
		DllCall('kernel32.dll', 'bool', 'FileTimeToSystemTime', 'ptr', $pLT, 'ptr', $pST)
		$sTime = StringFormat('%02d-%02d-' & DllStructGetData($tST, 'Year') & '   %02d:%02d:%02d', DllStructGetData($tST, 'Day'), DllStructGetData($tST, 'Month'), DllStructGetData($tST, 'Hour'), DllStructGetData($tST, 'Minute'), DllStructGetData($tST, 'Second'))
;		ConsoleWrite($sTime & '   ' & $sFile & @CR)
	EndIf
	$aResult = DllCall('kernel32.dll', 'bool', 'FindNextFileW', 'ptr', $hFind[0], 'ptr', $pWFD)
Until (@error) Or (Not $aResult[0])
DllCall('kernel32.dll', 'bool', 'FindClose', $hFind[0])

ConsoleWrite(TimerDiff($Timer) & @CR)

Результат: 434 мс

Тоже самое, но только на чистом AutoIt:

Код:
#Include <WinAPI.au3>

Global Const $sPath = @SystemDir
Global Const $sMask = '*'

$Timer = TimerInit()

$hFind = FileFindFirstFile($sPath & '\' & $sMask)
If $hFind = -1 Then
	Exit
EndIf
While 1
    $sFile = FileFindNextFile($hFind)
    If @error Then
		ExitLoop
	EndIf
	$sTime = FileGetTime($sPath & '\' & $sFile)
	$sTime = $sTime[2] & '-' & $sTime[1] & '-' & $sTime[0] & '   ' & $sTime[3] & ':' & $sTime[4] & ':' & $sTime[5]
;	ConsoleWrite($sTime & '   ' & $sFile & @CR)
WEnd
FileClose($hFind)

ConsoleWrite(TimerDiff($Timer) & @CR)

Результат: 276 мс (~ в 1.6 раза быстрее)

;)
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Yashied извини я просто из твоего ответа не понял до конца
Ты написал:
Это будет работать быстрее, чем на AutoIt с использованием DllCall()
и тут же следом пишешь:
А без DllCall() и DllStruct... здесь ну никак не обойтись.
поэтому я запутался и не понял правильно ты уж извини
Спасибо за коды
Буду внимательно изучать


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

Yashied не подскажешь
Я делаю по такому алгоритму
делаю список файлов и потом сравниваю построчно списки
regshot 1.8.2 - я понимаю так не работает он снятую информацию держит в бинарном виде
Может так быстрее или я что то путаю
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 711
Теперь я ничего не понимаю.

:smile:
 

kzru_hunter

Осваивающий
Сообщения
144
Репутация
49
assch
Если в программе важна производительность, то пиши на С++
 
Автор
A

assch

Новичок
Сообщения
166
Репутация
4
Может быть на С++ было бы и лучше но как говорится лучше синица в руке чем журавль в небе.
Честно говоря в сообществе Autoit мне больше ндравиться. Меньше снобизма, больше отзывчивости.
Часто если не сказать больше помогают советами и даже готовыми примерами.
Спасибо всем за участие.
:IL_AutoIt_1:
 
Верх