PDA

Показать полную графическую версию : [решено] FileSetAttrib: Проблема с рекурсией


Страниц : [1] 2

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, либо что-то не так с файловой системой...

kaster
10-09-2009, 11:12
такой вопросик нескромный. а зачем рекурсия для файла?
рекурсивная обработка папки применяется когда необходимо проставить тот или иной атрибут не только папке но и всем подпапкам и файлам внутри нее. убери флаг рекурсии и все окэ ;)

Creat0R
10-09-2009, 12:33
snoitaleR,
почему не срабатывает рекурсивное изменение атрибутов для всех файлов FARMENU.INI?
А для некоторых срабатывает?
где искать ошибку
В файлах конечно, возможно они заблокированы.

kaster, зачем рекурсия для файла?
Раз автор темы пишет о проблеме рекурсивной установки аттрибута файла, значет оно так и нужно ему ;).

snoitaleR
10-09-2009, 12:36
У меня во многих папках есть локальное меню для FAR...
Я не хочу, чтобы данный файл был виден из проводника...
Утилита attrib.exe справляется с данной задачей...
Но удобнее было бы пользоваться скриптом AUTOIT...

Могу утверждать наверняка, что все файлы FARMENU.INI на диске полностью доступны для текущего пользователя, единственное, для некоторых из них уже установлены атрибуты "скрытый" и "системный"...
Я редактировал их совсем недавно стандартным инструментом FAR для работы с меню пользователя, никаких проблем...

kaster
10-09-2009, 12:42
Раз автор темы пишет о проблеме рекурсивной установки аттрибута файла, значет оно так и нужно ему . »
Я конечно не автор темы, и уж тем более не такой знаток тонкостей языка, как ты, но, как мне кажется (и это вполне логично), что рекурсионная обработка может относится только к папке в контексте вложенных в нее файлов и других папок. для одного файла, опять же по моему убеждению, нельзя применить рекурсию. для проверки, я взял файл, запустил обозначенный в шапке скрипт, получил ошибку. оно и понятно, нет папки, нет рекурсии. затем взял этот же файл, засунул ее в папку, запустил скрипт, все норм. и папка и файл внутри нее приобрели обозначенные атрибуты. опять же все норм. и вот теперь, снова хочется спросить, в терминах моего небогатого понимания языка, почему мой трюк прошел, а у автора нет? :) и опять же хочется спросить зачем нужна рекурсия там, где она неприменима :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) ставить ему атрибут, без флага рекурсии, так как он (флаг) позволяет применить атрибут только к папке и всему ее содержимому включая подпапки и файлы

Creat0R
10-09-2009, 12:55
единственное, для некоторых из них уже установлены атрибуты "скрытый" и "системный" »
Вот и выявили проблему - функция 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 отсутствует, то выдается ошибка и в последующих папках смена атрибутов не производится...

kaster
10-09-2009, 13:43
Да. пока не проверишь, не поймешь :teeth:
Папка не должна принимать аттрибуты, если указано имя файла. »
да, это я оговорился, файлы принимали. но не суть :)
Автор не трюками занимается, а хочет всего лишь понять почему скрипт выдаёт ошибку, я выше написал почему. »
да. действительно. а я по глупости, думал что раз че то не получается, то скрипт должен был ругнуться.Применима, читаем справку и ещё раз первый пост. »
повторение - мать учения. да, мне ее еще по всей видимости долго читать.

вобщем, snoitaleR, извини что ввел в заблуждение. действительно, как и говорит тебе гуру, у тебя условие стоит не очень хорошее, потому как не выполнится он может в самых ненужных местах, типа
для некоторых из них уже установлены атрибуты "скрытый" и "системный"... »
и Если в одной из вложенных папок файл FARMENU.INI отсутствует, то выдается ошибка и в последующих папках смена атрибутов не производится... »
нужно другое, более стабильное

snoitaleR
10-09-2009, 13:49
Не хотелось бы запускать attrib.exe из скрипта, когда есть встроенная функция...
Текстовые окна не очень приятны, кроме FAR...

kaster
10-09-2009, 14:05
ну опять же можно просто заходить скриптом во все папки и проверять наличие нужного файла и выставления нужного атрибута при нахождении

Creat0R
10-09-2009, 14:26
Нужно пройтись по всем папкам и подпапкам, найти нужный файл и если он удовлетворяет шаблону (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

Creat0R
10-09-2009, 14:43
можно просто заходить скриптом во все папки и проверять наличие нужного файла »
Это долго.

kaster
10-09-2009, 15:27
Это долго. »

да, вот такой скрипт

#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 тыс.

Creat0R
10-09-2009, 16:13
Если в одной из вложенных папок файл FARMENU.INI отсутствует, то выдается ошибка и в последующих папках смена атрибутов не производится... »
А вот это уже бага в функции... нужно проверить.

snoitaleR
10-09-2009, 16:55
Creat0R, kaster, полезные алгоритмы, спасибо...
Иногда бывает необходимость пробежать все папки на диске...

snoitaleR
14-09-2009, 09:08
Creat0R, проверь, пожалуйста, действительно ли ошибка внутри функции FileSetAttrib, чтобы я уже не сомневался и мог поставить отметку [решено]...

Creat0R
14-09-2009, 13:39
действительно ли ошибка внутри функции FileSetAttrib »
Да, написал баг репорт (тикет № 1176 (http://www.autoitscript.com/trac/autoit/ticket/1176)).

snoitaleR
14-09-2009, 13:43
Пока будем использовать альтернативные варианты... :)
Будем считать тему решенной...

Creat0R
14-09-2009, 13:55
Пока будем использовать альтернативные варианты »
Я кстати поправил свою функцию выше (http://forum.oszone.net/post-1215681.html#post1215681), спасибо amel27 за RegExp'сы :)




© OSzone.net 2001-2012