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

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

snoitaleR 10-09-2009 11:05 1215460

FileSetAttrib: Проблема с рекурсией
 
Подскажите, пожалуйста, почему не срабатывает рекурсивное изменение атрибутов для всех файлов 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 1215463

такой вопросик нескромный. а зачем рекурсия для файла?
рекурсивная обработка папки применяется когда необходимо проставить тот или иной атрибут не только папке но и всем подпапкам и файлам внутри нее. убери флаг рекурсии и все окэ ;)

Creat0R 10-09-2009 12:33 1215532

snoitaleR,
Цитата:

почему не срабатывает рекурсивное изменение атрибутов для всех файлов FARMENU.INI?
А для некоторых срабатывает?
Цитата:

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

kaster,
Цитата:

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

snoitaleR 10-09-2009 12:36 1215537

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

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

kaster 10-09-2009 12:42 1215552

Цитата:

Цитата Creat0R
Раз автор темы пишет о проблеме рекурсивной установки аттрибута файла, значет оно так и нужно ему . »

Я конечно не автор темы, и уж тем более не такой знаток тонкостей языка, как ты, но, как мне кажется (и это вполне логично), что рекурсионная обработка может относится только к папке в контексте вложенных в нее файлов и других папок. для одного файла, опять же по моему убеждению, нельзя применить рекурсию. для проверки, я взял файл, запустил обозначенный в шапке скрипт, получил ошибку. оно и понятно, нет папки, нет рекурсии. затем взял этот же файл, засунул ее в папку, запустил скрипт, все норм. и папка и файл внутри нее приобрели обозначенные атрибуты. опять же все норм. и вот теперь, снова хочется спросить, в терминах моего небогатого понимания языка, почему мой трюк прошел, а у автора нет? :) и опять же хочется спросить зачем нужна рекурсия там, где она неприменима :teeth:

Выдержка из справки
Цитата:

Цитата Справка AutoIt
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 1215569

Цитата:

Цитата snoitaleR
единственное, для некоторых из них уже установлены атрибуты "скрытый" и "системный" »

Вот и выявили проблему - функция FileSetAttrib возвращает 0 если она не смогла установить аттрибут для всех файлов (хотя в справке об этом не пишется, а должны были пометку сделать как минимум).


Цитата:

Цитата kaster
рекурсионная обработка может относится только к папке в контексте вложенных в нее файлов и других папок. для одного файла, опять же по моему убеждению, нельзя применить рекурсию. »

А кто говорит об одном файле? Перечитай первый пост. Там же явно написано про рекурсию. Ты почему то убеждён что для snoitaleR'а рекурсия не нужна :idontnow:


Цитата:

Цитата kaster
затем взял этот же файл, засунул ее в папку, запустил скрипт, все норм. и папка и файл внутри нее приобрели обозначенные атрибуты. »

Папка не должна принимать аттрибуты, если указано имя файла.

Цитата:

Цитата kaster
почему мой трюк прошел, а у автора нет? »

Автор не трюками занимается, а хочет всего лишь понять почему скрипт выдаёт ошибку, я выше написал почему.

Цитата:

Цитата kaster
опять же хочется спросить зачем нужна рекурсия там, где она неприменима »

Применима, читаем справку и ещё раз первый пост.

snoitaleR 10-09-2009 13:04 1215581

Если очень интересно, то:
Код:

attrib +h +s farmenu.ini /s
работает без проблем...

snoitaleR 10-09-2009 13:25 1215613

kaster, скорее всего, не в этом причина...
Я добавил "звездочку" перед именем файла - та же ошибка выпадает...
Попробую снять атрибуты со всех файлов, потом посмотрю, после какого файла (перед каким файлом) происходит остановка...

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

kaster 10-09-2009 13:43 1215638

Да. пока не проверишь, не поймешь :teeth:
Цитата:

Цитата Creat0R
Папка не должна принимать аттрибуты, если указано имя файла. »

да, это я оговорился, файлы принимали. но не суть :)
Цитата:

Цитата Creat0R
Автор не трюками занимается, а хочет всего лишь понять почему скрипт выдаёт ошибку, я выше написал почему. »

да. действительно. а я по глупости, думал что раз че то не получается, то скрипт должен был ругнуться.
Цитата:

Цитата Creat0R
Применима, читаем справку и ещё раз первый пост. »

повторение - мать учения. да, мне ее еще по всей видимости долго читать.

вобщем, snoitaleR, извини что ввел в заблуждение. действительно, как и говорит тебе гуру, у тебя условие стоит не очень хорошее, потому как не выполнится он может в самых ненужных местах, типа
Цитата:

Цитата snoitaleR
для некоторых из них уже установлены атрибуты "скрытый" и "системный"... »

и
Цитата:

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

нужно другое, более стабильное

snoitaleR 10-09-2009 13:49 1215646

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

kaster 10-09-2009 14:05 1215654

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

Creat0R 10-09-2009 14:26 1215681

Цитата:

Цитата kaster
Нужно пройтись по всем папкам и подпапкам, найти нужный файл и если он удовлетворяет шаблону (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 1215696

Цитата:

Цитата kaster
можно просто заходить скриптом во все папки и проверять наличие нужного файла »

Это долго.

kaster 10-09-2009 15:27 1215730

Цитата:

Цитата Creat0R
Это долго. »

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

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

Цитата:

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

А вот это уже бага в функции... нужно проверить.

snoitaleR 10-09-2009 16:55 1215846

Creat0R, kaster, полезные алгоритмы, спасибо...
Иногда бывает необходимость пробежать все папки на диске...

snoitaleR 14-09-2009 09:08 1218383

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

Creat0R 14-09-2009 13:39 1218576

Цитата:

Цитата snoitaleR
действительно ли ошибка внутри функции FileSetAttrib »

Да, написал баг репорт (тикет № 1176).

snoitaleR 14-09-2009 13:43 1218583

Пока будем использовать альтернативные варианты... :)
Будем считать тему решенной...

Creat0R 14-09-2009 13:55 1218595

Цитата:

Цитата snoitaleR
Пока будем использовать альтернативные варианты »

Я кстати поправил свою функцию выше, спасибо amel27 за RegExp'сы :)

snoitaleR 14-09-2009 14:47 1218668

Я как раз недавно читал ваше обсуждение, случайно...
Для меня регулярные выражения - это сверхъестественное...
Могу только копировать... :)


Время: 05:28.

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