Показать полную графическую версию : [решено] FileSetAttrib: Проблема с рекурсией
snoitaleR
10-09-2009, 11:05
Подскажите, пожалуйста, почему не срабатывает рекурсивное изменение атрибутов для всех файлов FARMENU.INI?
If Not FileSetAttrib("c:\farmenu.ini", "+HS", 1) Then
MsgBox(4096,"Error", "Problem setting attributes.")
EndIf
Скрипт выдает сообщение "Problem setting attributes."
Не знаю, где искать ошибку: либо неверно составил скрипт, либо ошибка внутри AUTOIT, либо что-то не так с файловой системой...
такой вопросик нескромный. а зачем рекурсия для файла?
рекурсивная обработка папки применяется когда необходимо проставить тот или иной атрибут не только папке но и всем подпапкам и файлам внутри нее. убери флаг рекурсии и все окэ ;)
snoitaleR,
почему не срабатывает рекурсивное изменение атрибутов для всех файлов FARMENU.INI?
А для некоторых срабатывает?
где искать ошибку
В файлах конечно, возможно они заблокированы.
kaster, зачем рекурсия для файла?
Раз автор темы пишет о проблеме рекурсивной установки аттрибута файла, значет оно так и нужно ему ;).
snoitaleR
10-09-2009, 12:36
У меня во многих папках есть локальное меню для FAR...
Я не хочу, чтобы данный файл был виден из проводника...
Утилита attrib.exe справляется с данной задачей...
Но удобнее было бы пользоваться скриптом AUTOIT...
Могу утверждать наверняка, что все файлы FARMENU.INI на диске полностью доступны для текущего пользователя, единственное, для некоторых из них уже установлены атрибуты "скрытый" и "системный"...
Я редактировал их совсем недавно стандартным инструментом FAR для работы с меню пользователя, никаких проблем...
Раз автор темы пишет о проблеме рекурсивной установки аттрибута файла, значет оно так и нужно ему . »
Я конечно не автор темы, и уж тем более не такой знаток тонкостей языка, как ты, но, как мне кажется (и это вполне логично), что рекурсионная обработка может относится только к папке в контексте вложенных в нее файлов и других папок. для одного файла, опять же по моему убеждению, нельзя применить рекурсию. для проверки, я взял файл, запустил обозначенный в шапке скрипт, получил ошибку. оно и понятно, нет папки, нет рекурсии. затем взял этот же файл, засунул ее в папку, запустил скрипт, все норм. и папка и файл внутри нее приобрели обозначенные атрибуты. опять же все норм. и вот теперь, снова хочется спросить, в терминах моего небогатого понимания языка, почему мой трюк прошел, а у автора нет? :) и опять же хочется спросить зачем нужна рекурсия там, где она неприменима :teeth:
Выдержка из справки
file pattern File(s) to change, e.g. C:\*.au3, C:\Dir
+-RASHNOT Attribute(s) to set/clear. e.g. "+A", "+RA-SH"
recurse [optional] If this is set to 1, then directories are recursed into. Default is 0 (no recursion).
snoitaleR, могу посоветовать следующее, если не прав, знающие меня надеюсь поправят
Нужно пройтись по всем папкам и подпапкам, найти нужный файл и если он удовлетворяет шаблону (farmenu.ini) ставить ему атрибут, без флага рекурсии, так как он (флаг) позволяет применить атрибут только к папке и всему ее содержимому включая подпапки и файлы
единственное, для некоторых из них уже установлены атрибуты "скрытый" и "системный" »
Вот и выявили проблему - функция FileSetAttrib возвращает 0 если она не смогла установить аттрибут для всех файлов (хотя в справке об этом не пишется, а должны были пометку сделать как минимум).
рекурсионная обработка может относится только к папке в контексте вложенных в нее файлов и других папок. для одного файла, опять же по моему убеждению, нельзя применить рекурсию. »
А кто говорит об одном файле? Перечитай первый пост. Там же явно написано про рекурсию. Ты почему то убеждён что для snoitaleR'а рекурсия не нужна :idontnow:
затем взял этот же файл, засунул ее в папку, запустил скрипт, все норм. и папка и файл внутри нее приобрели обозначенные атрибуты. »
Папка не должна принимать аттрибуты, если указано имя файла.
почему мой трюк прошел, а у автора нет? »
Автор не трюками занимается, а хочет всего лишь понять почему скрипт выдаёт ошибку, я выше написал почему.
опять же хочется спросить зачем нужна рекурсия там, где она неприменима »
Применима, читаем справку и ещё раз первый пост.
snoitaleR
10-09-2009, 13:04
Если очень интересно, то:
attrib +h +s farmenu.ini /s
работает без проблем...
snoitaleR
10-09-2009, 13:25
kaster, скорее всего, не в этом причина...
Я добавил "звездочку" перед именем файла - та же ошибка выпадает...
Попробую снять атрибуты со всех файлов, потом посмотрю, после какого файла (перед каким файлом) происходит остановка...
Я, кажется, понял логику ошибки, но с моей логикой эта логика не совместима...
Если в одной из вложенных папок файл FARMENU.INI отсутствует, то выдается ошибка и в последующих папках смена атрибутов не производится...
Да. пока не проверишь, не поймешь :teeth:
Папка не должна принимать аттрибуты, если указано имя файла. »
да, это я оговорился, файлы принимали. но не суть :)
Автор не трюками занимается, а хочет всего лишь понять почему скрипт выдаёт ошибку, я выше написал почему. »
да. действительно. а я по глупости, думал что раз че то не получается, то скрипт должен был ругнуться.Применима, читаем справку и ещё раз первый пост. »
повторение - мать учения. да, мне ее еще по всей видимости долго читать.
вобщем, snoitaleR, извини что ввел в заблуждение. действительно, как и говорит тебе гуру, у тебя условие стоит не очень хорошее, потому как не выполнится он может в самых ненужных местах, типа
для некоторых из них уже установлены атрибуты "скрытый" и "системный"... »
и Если в одной из вложенных папок файл FARMENU.INI отсутствует, то выдается ошибка и в последующих папках смена атрибутов не производится... »
нужно другое, более стабильное
snoitaleR
10-09-2009, 13:49
Не хотелось бы запускать attrib.exe из скрипта, когда есть встроенная функция...
Текстовые окна не очень приятны, кроме FAR...
ну опять же можно просто заходить скриптом во все папки и проверять наличие нужного файла и выставления нужного атрибута при нахождении
Нужно пройтись по всем папкам и подпапкам, найти нужный файл и если он удовлетворяет шаблону (farmenu.ini) ставить ему атрибут »
Тогда уже проще вызвать attrib из ком. строки:
If Not _FileSetAttribEx("c:\farmenu.ini", "+HS", 1) Then
MsgBox(4096, "Error", "Problem setting attributes.")
EndIf
;Флаг = 1 -> Обработка файлов с указанными именами в текущей папке и во всех ее подпапках.
;Флаг = 2 -> Обработка и файлов, и папок.
;Флаги можно совмещать (BitOR(1, 2)).
Func _FileSetAttribEx($sFilePattern, $sAttributes, $iFlag=0)
Local $sFlags = ""
$sAttributes = StringRegExpReplace( _
StringStripWS($sAttributes, 8), _
"[-+]?([^-+])(?<=([-+])[^-+]|([-+])[^-+]{2}|([-+])[^-+]{3}|([-+])[^-+]{4}|([-+])[^-+]{5}|([-+])[^-+]{6}|([-+])[^-+]{7})", _
" \2\3\4\5\6\7\8\1")
If BitAND($iFlag, 1) = 1 Then $sFlags &= " /S "
If BitAND($iFlag, 2) = 2 Then $sFlags &= " /D "
Local $iPID = Run(@ComSpec & ' /C Attrib ' & $sAttributes & $sFlags & '"' & $sFilePattern & '"', '', @SW_HIDE, 2)
Local $iError = @error, $sStdRead = ""
While ProcessExists($iPID)
Sleep(10)
$sStdRead &= StdoutRead($iPID)
If @error Then ExitLoop
WEnd
Return (Number($iError = 0) + Number(StringRegExp($sStdRead, ": \w:\\") = 0) = 2)
EndFunc
можно просто заходить скриптом во все папки и проверять наличие нужного файла »
Это долго.
Это долго. »
да, вот такой скрипт
#include <File.au3>
$j = 0
$start = TimerInit()
_Setter('c:')
$time = TimerDiff($start) / 1000
MsgBox(0, 'Time', $time & ' seconds elapsed' & @CRLF & $j & ' files scanned')
Func _Setter($sPath)
Local $aAll = _FileListToArray($sPath)
If Not IsArray($aAll) Then Return
For $i = 1 To $aAll[0]
If _PathIsFolder($sPath & '\' & $aAll[$i]) Then
$sNew_Path = $sPath & '\' & $aAll[$i]
;$iTotal_Folders += 1
_Setter($sNew_Path)
Else
$j += 1
If $aAll[$i] = 'farmenu.ini' Then FileSetAttrib($sPath & '\' & $aAll[$i], '+SH')
EndIf
Next
Return
EndFunc
Func _PathIsFolder($sPath)
Return StringInStr(FileGetAttrib($sPath), "D")
EndFunc
выполнялся 15 секунд против 5 секунд с этим примером
$start = TimerInit()
RunWait(@ComSpec & ' /C attrib +h +s farmenu.url /s', 'c:\', @SW_HIDE)
$time = TimerDiff($start) / 1000
MsgBox(0, 'Time', $time & ' seconds elapsed')
PS: кол-во файлов на диске С у меня ~175 тыс.
Если в одной из вложенных папок файл FARMENU.INI отсутствует, то выдается ошибка и в последующих папках смена атрибутов не производится... »
А вот это уже бага в функции... нужно проверить.
snoitaleR
10-09-2009, 16:55
Creat0R, kaster, полезные алгоритмы, спасибо...
Иногда бывает необходимость пробежать все папки на диске...
snoitaleR
14-09-2009, 09:08
Creat0R, проверь, пожалуйста, действительно ли ошибка внутри функции FileSetAttrib, чтобы я уже не сомневался и мог поставить отметку [решено]...
действительно ли ошибка внутри функции FileSetAttrib »
Да, написал баг репорт (тикет № 1176 (http://www.autoitscript.com/trac/autoit/ticket/1176)).
snoitaleR
14-09-2009, 13:43
Пока будем использовать альтернативные варианты... :)
Будем считать тему решенной...
Пока будем использовать альтернативные варианты »
Я кстати поправил свою функцию выше (http://forum.oszone.net/post-1215681.html#post1215681), спасибо amel27 за RegExp'сы :)
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.
Available in ZeroNet 1osznRoVratMCN3bFoFpR2pSV5c9z6sTC