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

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Рекурсивный обход папок в WSH на JS (http://forum.oszone.net/showthread.php?t=199327)

petrovre 12-02-2011 22:51 1611357

Рекурсивный обход папок в WSH на JS
 
Задача: Есть папка, в которой присутствует некоторое неограниченное количество подпапок. Надо обойти их все и вывести на экран названия.
Проблема: Сделал такой вот скрипт, который вызывает рекурсивную функцию, но почему-то он обходит дерево подпапок только до первого листа, а потом заканчивает работу в штатном режиме, без каких-либо ошибочных кодов. Подскажите, где я ошибаюсь:

Код:

//объект файловой системы
var fso = new ActiveXObject("Scripting.FileSystemObject");
//путь к каталогу, откуда запускается скрипт
var path = WScript.ScriptFullName.substr(0, (WScript.ScriptFullName.length - WScript.ScriptName.length)), 
p = fso.GetFolder(path);

//Вызываем рекурсивную функцию
sFolders(path);

//Собственно рекурсивная функция
function sFolders(folder)//полный путь
{
        //доступ к объекту-папке
        root = fso.GetFolder(folder);
        //Коллекция подпапок
        sfCount = root.SubFolders.Count;
        //последовательность подпапок
        seq = new Enumerator(root.SubFolders)
        WScript.Echo("\nКоличество подпапок в корневой папке (" + root + ") = " + sfCount)
        //если в текущей папке есть подпапки, то вызываем функцию для каждой подпапки рекурсивно.
        if(sfCount > 0)

        for(; !seq.atEnd(); seq.moveNext())
        {
                WScript.Echo("Путь к подпапке = " + seq.item().path)
                //вызываем функцию рекурсивно
                sFolders(seq.item().path);
        }
}

На данный момент ситуация такова, что если мы имеем такую структуру папок:

- "Тест"
--- "1"
------ "1-1"
--- "2"
------ "2-1"

То скрипт отрабатывает вплоть до папки "1-1", а после этого заканчивает работу, т.е. создаётся ощущение, что не срабатывает метод seq.moveNext().

Ivan Bardeen 14-02-2011 10:07 1612438

Вот скрипт, с подобным функционалом на VBS - надеюсь поможет разобраться
Код:

Set FSO = CreateObject("Scripting.FileSystemObject")
ShowSubFolders FSO.GetFolder("C:\temp")

Sub ShowSubFolders(Folder)
    For Each Subfolder in Folder.SubFolders
        Wscript.Echo Subfolder.Name
        ShowSubFolders Subfolder
    Next
End Sub


petrovre 14-02-2011 20:27 1612922

Спасибо, конечно, но этот скрипт я несколько раз находил, пытаясь нагуглить решение своей проблемы. Принцип у меня тот же самый, но на JS этот способ почему-то не работает.

Ivan Bardeen 14-02-2011 20:42 1612932

petrovre,
VBS для этих целей гораздо удобней, как вы видите - для vbscript, к примеру, не нужно объявлять массив. Больше типов данных, больше готовых примеров. Для автоматизации действий в windows подходит больше именно vbscript, имхо. Начал я c JScript, полгода поработал, потом переучился на VBS

megaloman 16-02-2011 00:11 1614007

Вот рекурсия на VBS
Код:

AllDir = "P:\DDDDDD"                    ' ---------  Полное имя рабочего каталога (без слэжа \ на конце)

OutStr = AllDir + vbCrLf
OutStr = OutStr + AllFolders(AllDir)

MsgBox OutStr

' ---------------------------------------------------------------------------
Function AllFolders(WDir)
'  MsgBox WDir
    Rezult = ""
    Set F = CreateObject("Scripting.FileSystemObject").GetFolder(WDir)
    Set SubF = F.SubFolders

    For Each Folder In SubF
        Rezult = Rezult + WDir + "\" + Folder.Name + vbCrLf
        Rezult = Rezult + AllFolders(WDir + "\" + Folder.Name)
    Next

    AllFolders = Rezult
End Function

Вот рекурсия на JS
Код:

var AllDir = "P:\\dddddd";          //---------  Полное имя рабочего каталога (без слэжа \\ на конце)

var OutStr=AllDir+"\n";

OutStr+=AllFolders(AllDir);

WScript.Echo(OutStr);

// ---------------------------------------------------------------------------
function AllFolders(WDir)
{
//    WScript.Echo(WDir);
    var F,Rezult,Folders;

    F=WScript.CreateObject("Scripting.FileSystemObject").GetFolder(WDir);
    Rezult="";

    Folders=new Enumerator(F.SubFolders);

    for (; !Folders.atEnd(); Folders.moveNext())
    {
//      WScript.Echo(Folders.item().Name);
      Rezult+=WDir+"\\"+Folders.item().Name+"\n";
      Rezult+=AllFolders(WDir+"\\"+Folders.item().Name);
    }

    return Rezult;
}

Всё дело в видимости переменных в JS. Пока в функции не написал:
var F,Rezult,Folders;
у меня тоже не работало.

petrovre 20-02-2011 22:44 1617957

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


Время: 06:53.

Время: 06:53.
© OSzone.net 2001-