Цитата:
|
kosmonavtom, во-первых, смените тон. Вам тут никто ничего не обязан, тем не менее стараются помочь кто как может. А задуматься следует вам, напр. над тем, что возможна ситуация, когда кто-то либо не знает ответа на ваш вопрос настолько хорошо, чтобы сходу написать работающий пример, либо просто не имеет времени, но знает, что найти ответ можно в конкретном месте. Он за вас должен там его искать? Что плохого в том, что хотел помочь и порекомендовал книги?
А если у вас мое предложение по поводу запуска не работает, то вы что-то делаете не так, либо (что более вероятно) просто нагло врете. Я этим пользуюсь уже много лет, и под 2000, и под XP, и под семеркой. Ваш же пример у меня при запуске выводит информацию в консоль. Если бы у вас это не работало, вы, вместо того, чтобы учить других как вести себя на форуме, рассказали бы что именно не работает - не запускается вообще, или запускается и не выводит ничего в консоль. И что делает простейшая программи в одну строчку, типа: WScript.Echo( "test" ); если запустить ее cscript test.js И что происходит если сказать cscript //H:cscript ну и т.д., т.е. вы пытались бы разобраться в вопросе, который вас поначалу интересовал, а не учили бы старожилов форума, на который вы только что пришли, "хорошим манерам" |
rgl, так все таки прав, Тс пишет не на js?
|
Цитата:
Если вопрос ко мне, то я уже некоторое время назад понял безуспешность отстаивания своего мнения на форумах, ибо есть форумы про JavaScript в браузерах, и нет форумов про JavaScript вне браузеров. А на тех форумах что есть, побеждают в споре в подобном вопросе большинством, а большинсво заранее уверено в своей правоте и даже не пытается вникнуть в доводы оппонента. Мое мнение - вы тут готовы друг другу глотки перегрызть в споре о том, JScript и JavaScript - одно и то же или совершенно разные языки. А вопрос то не в сути, а в терминологии, не договорившись что обозначает данный конкретный термин, нельзя спорить применим ли он в каком-то конкретном случае или нет. Если принять по определению, что JavaScript - язык браузеров, то утверждение "вре браузеров JavaScript нет" становится тавтологией. А если принять по определению, что JavaScript - это реализация стандарта ECMA-262 от фирмы Netscape, то тот язык, что в IE и в опере - уже не JavaScript. Назовем термином xerox только агрегаты, выпущенные одноименной фирмой, и копировальный аппарат, стоящий в соседней комнате - никакой не ксерокс. Я же склонен называть термином JavaScript язык, соответствующий всем известному стандарту, в котором ничего не говорится про браузер, про объектную модель документа. Это принято называть базовым JavaScript, и микрософтовский JScript несомненно таковым является. Когда мы добавляем объекты браузера и документа, это уже клиентский JavaScript, но мне такое название не нравится и вот почему - все конструкции языка - простые операторы, циклы, условные операторы, функции, объекты и массивы, регулярные выражения - все это определено в базовом языке, клиентский же - это объекты документа, с которыми можно работать на JavaScript, но (иногда) можно и на VBScript, т.е. это уже находится вне языка, а язык (тот, который есть) имеет к этому доступ. Поэтому я под JavaScript понимаю именно базовый язык, а название JScript говорит не о том, что это "совсем другой язык, не имеющий ничего общего" а о войне терминов. |
kosmonavtom, закралось подозрение, может скрипт отрабатывает так быстро, что вы просто не успеваете увидеть консоль? Тогда попробуйте вставить в конце своего скрипта что-то вроде:
WScript.Sleep(5000); |
rgl,
1) Ну понятно, спасибо за разъяснения. Просто обычно люди общаются на форуме и приходят к какому -то решению конструктивному. А тут что-то все ругаются вместо изучения. 2) нет на самом деле я пишу команду script в cmd? а у меня выдается, что мул "script" не является внутренней или внешней командой, исполняемой программой или пакетным файлом. Может что-то не так и не туда написал? deff, речь о том, что я и не просил ни у кого "сигарет" нет возможности реально подсказать, так лучше вообще ничего не пишите в теме. |
Цитата:
Запустить скрипт можно несколькими способами. Не все, но существенные для обсуждаемого вопроса способы: wscript filename.js (буковка W вначале очень важна) в этом случае, если в скрипте есть команды Echo, они будут выводить информацию в модальное окно и заставлять кликать мышкой. cscript filename.js (буковка c в начале тоже необходима) в этом случае, во-первых, команда echo будет выводить информацию на консоль, но кроме того появляется более продвинуная возможность писать в stdout и stderr а также читать из stdin и наконец, можно просто набрать имя файла test.js в этом случае скрипт запустится одним из двух вышеупомянутых способов, каким именно - зависит от настроек операционки. Поменять данную настройку операционки проще всего с помощью команд cscript //H:cscript cscript //H:wscript если набрать cscript без параметров, можно почитать коротенький хэлп |
спасибо за подсказку. Все получилось :) вот теперь как это выглядит:
var wsh = new ActiveXObject("WScript.Shell"); // var cmd = wsh.Exec("cmd /c cscript //H:cscript"); var cmd = wsh.Exec("cmd /c cscript rekursya.js"); if (cmd.Status === 0) { // 1 Взято но не рабочее с сайта: [url]http://forum.oszone.net/nextnewesttothread-199998.html[/url] // 2объект файловой системы var fso = new ActiveXObject("Scripting.FileSystemObject"); // 4 путь к каталогу, откуда запускается скрипт var path = WScript.ScriptFullName.substr(0, (WScript.ScriptFullName.length - WScript.ScriptName.length)), p = fso.GetFolder(path); var vsePapki = []; //Массив записей путей ко всем подпапкам. var nomerProverki=0; //Количество провереных и обработанных папок. var nomerZapisi=1; // Количество записанных папок в массив. //12 Вызываем рекурсивную функцию sFolders(path); //14 Рекурсивная функция перебора всех папок и подпапок } function sFolders(folder)//полный путь { // 17 доступ к объекту-папке var root = fso.GetFolder(folder); // 19 Коллекция подпапок var sfCount = root.SubFolders.Count; // 21 последовательность подпапок var seq = new Enumerator(root.SubFolders); // WScript.Echo("\nКоличество подпапок в корневой папке (" + root + ") = " + sfCount); // 24 если в текущей папке есть подпапки, то вызываем функцию для каждой подпапки рекурсивно. while (sfCount>0) { for(; !seq.atEnd(); seq.moveNext()) { // WScript.Echo("Путь к подпапке = " + seq.item().path); vsePapki[nomerZapisi] = seq.item().path; nomerZapisi=nomerZapisi+1; // Количество записей в массиве адресов } nomerProverki=nomerProverki+1; WScript.Echo("Номер проверки = " + nomerProverki + " Номер записи = " + [nomerZapisi-1]); if (nomerProverki>=nomerZapisi) { sfCount = 0; } else { WScript.Echo("ПАПКА НА ПРОВЕРКУ = " + vsePapki[nomerProverki]); sfCount = sfCount - 1; sFolders(vsePapki[nomerProverki]); } } } |
О! только у меня закралось подозрение, что скрипт выполняется два раза :( один раз просто при запуске, а второй раз при запуске через cmd. - ну ладно подумаю еще доработаю - самое главное он информацию выводит в cmd )))
|
Цитата:
var cmd = wsh.Exec("cmd /c cscript rekursya.js"); Удивительно что только два раза, а не больше. Запускайте скрипт сразу с консоли комадной cscript C:\>cscript rekursya.js либо же замените var cmd = wsh.Exec("cmd /c cscript rekursya.js"); на if( ! /cscript\.exe$/.test( WScript.FullName ) ) { // проверить что запущено в консольном режиме wsh.Run("cmd /c cscript " + WScript.ScriptName ); // если нет, перезапустить в консоли WScript.Quit(0); // и завершить текущую инкарнацию (пусть работает перезапущенный в консоли) } |
rgl, внутри скрипта это нужно, чтобы пользователь щелкнул на единственный файл, а не запускал лишние консоли и прочее. И я думаю он не будет большее количество раз выполняться ведь именно для этого там и стоит if ...
|
kosmonavtom, а почему и именно скриптовый язык, почему бы не воспользоваться тем же C# он не на много сложнее, проблема в размере файла?
|
kosmonavtom,
Смотрите мое поправленное предыдущее сообщение cyber, этот язык уже есть, есть всегда и у всех (под Windows, разумеется) а всякие там C#, перлы и питоны нужно устанавливать, что не всегда хочется, и не всегда возможно. |
Цитата:
|
rgl, спасибо за новое условие :) - не знал раньше о таких вещах. А вот код в итоге работает еще и без моего условия и без повторного перезапуска, а просто с двумя строками вначале следующего вида:
var wsh = new ActiveXObject("WScript.Shell"); var cmd = wsh.Exec("cmd /c cscript //H:cscript"); // Перенастройка системы на консольный режим работы и это я так понимаю самое простое решение для моей рекурсии. Но твое условие я все же думаю оставить в коде т.к. мало ли будут пользователи у которых не успеет консольный режим включиться. Конечный вариант пока посмотрю на всех машинах, а потом выложу в тему. |
Цитата:
Цитата:
Да, и в моем варианте лучше чуть-чуть подправить: if( ! /cscript\.exe$/i.test( WScript.FullName ) ) { // проверить что запущено в консольном режиме (Добавить буковку i, чтобы было нечувствительно к регистру) |
rgl,
Цитата:
|
В процессе эксплуатации возникла новая фишка. Теперь оказалось, что если рекурсия натыкается на папку к которой у пользователя нет доступа, то он вылетает. Для исправления ситуации и продолжения работы скрипта, не глядя на эту папку, я решил добавить условие вида: if (path.StdErr == 0) - оно там есть в скрипте ниже. Но после этого скрипт виснет и жрет 50% ЦП!!! Я что, не правильно записал проверку ошибок?
//var wsh = new ActiveXObject("WScript.Shell"); //if( ! /cscript\.exe$/.test( WScript.FullName ) ) { // проверить что запущено в консольном режиме // wsh.Run("cmd /c cscript " + WScript.ScriptName ); // если нет, перезапустить в консоли // WScript.Quit(0); // и завершить текущую инкарнацию (пусть работает перезапущенный в консоли) //} // 1 Взято но не рабочее с сайта: [url]http://forum.oszone.net/nextnewesttothread-199998.html[/url] // 2объект файловой системы var fso = new ActiveXObject("Scripting.FileSystemObject"); // 4 путь к каталогу, откуда запускается скрипт var path = WScript.ScriptFullName.substr(0, (WScript.ScriptFullName.length - WScript.ScriptName.length)), p = fso.GetFolder(path); var vsePapki = []; //Массив записей путей ко всем подпапкам. var nomerProverki=0; //Количество провереных и обработанных папок. var nomerZapisi=1; // Количество записанных папок в массив. //12 Вызываем рекурсивную функцию sFolders(path); //14 Рекурсивная функция перебора всех папок и подпапок function sFolders(folder)//полный путь { // 17 доступ к объекту-папке var root = fso.GetFolder(folder); // 19 Коллекция подпапок var sfCount = root.SubFolders.Count; // 21 последовательность подпапок var seq = new Enumerator(root.SubFolders); // WScript.Echo("\nКоличество подпапок в корневой папке (" + root + ") = " + sfCount); // 24 если в текущей папке есть подпапки, то вызываем функцию для каждой подпапки рекурсивно. while (sfCount>0) { for(; !seq.atEnd(); seq.moveNext()) { // WScript.Echo("Путь к подпапке = " + seq.item().path); vsePapki[nomerZapisi] = seq.item().path; nomerZapisi=nomerZapisi+1; // Количество записей в массиве адресов } if (path.StdErr == 0) // КАК проверить будет ли ошибка у этой папки???? { nomerProverki=nomerProverki+1; WScript.Echo("Номер проверки = " + nomerProverki + " Номер записи = " + [nomerZapisi-1]); if (nomerProverki>=nomerZapisi) { sfCount = 0; } else { WScript.Echo("ПАПКА НА ПРОВЕРКУ = " + vsePapki[nomerProverki]); sfCount = sfCount - 1; sFolders(vsePapki[nomerProverki]); } } } } WScript.Sleep(99000); |
Цитата:
|
rgl, спасибо. Значит я так понял что мне нужно:
1) Поставить строку проверки читабельности папки между 37 и 38 т.к. например системную папку лучше и не записывать в массив записанных адресов тогда вообще. 2) Проверять seq.item().path - но не получается, может не правильно указываю свойства?! Ввести вместо vsePapki[nomerZapisi] еще одну переменную и у нее свойства проверить?! - выберу когда свойства папок найду. 3) И проверить системная ли эта папка? или же есть ли у пользователя к ней доступ? - что-то вроде этого. Только как? Ладно будем искать... но пока погуглю свойства папки наверно. |
Вместо того, чтобы пытаться с помощью форума исправить найденный непонятногде говнокод, лучше было бы это время и усилия потратить на то, чтобы разобраться в теме и написать нормально самому.
Мои замечания к приведенному коду: 1. Непонятно зачем тут вложенные циклы, снаружи while а внутри for. Достаточно одного. 2. Непонятно зачем многократно преобразовывать текстовую строку в объект типа фолдер и обратно. Лучше рекурсивной функции передавать сам объект а не строку, а преобразовывать в строку только для сообщения на консоль. 3. Чтобы найти текущую дирректорию (начальную) не нужны манипуляции с полным именем скрипта, для этого есть специальное свойство. 4. Хотя этот кусок и закомментарен сейчас, к регулярному выражению лучше добавить буковку i, я уже писал об этом. 5. Не надо использовать имя переменной root для обозначения каждой дирректории, сколь угодно глубоко вложенной. Затрудняет чтение (и понимание) кода. 6. Также затрудняет чтение и вносит путаницу имя переменной path, когда есть и используется одноименное свойство С учетом всего этого получается: var wsh = WScript.CreateObject("WScript.Shell"); //if( ! /cscript\.exe$/i.test( WScript.FullName ) ) { // проверить что запущено в консольном режиме // wsh.Run("cmd /c cscript " + WScript.ScriptName ); // если нет, перезапустить в консоли // WScript.Quit(0); // и завершить текущую инкарнацию (пусть работает перезапущенный в консоли) //} var fso = WScript.CreateObject("Scripting.FileSystemObject"); //var curdir = wsh.CurrentDirectory; // получаем текущую дирректорию (строку) //var root = fso.GetFolder(curdir); // текущая дирректория (объект типа фолдер) //sFolders(root); // вызываем рекурсивную функцию первый раз sFolders(fso.GetFolder(wsh.CurrentDirectory)); function sFolders(dir) { for( var seq = new Enumerator(dir.SubFolders); !seq.atEnd(); seq.moveNext()) { WScript.Echo( "ПАПКА НА ПРОВЕРКУ = " + seq.item().path ); sFolders( seq.item() ) } } |
rgl, Вот это спасибо! Вот это КПД :victory: Спасибо за разъяснения, спасибо за помощь. Отдельное спасибо за замечания и абсолютно новые вещи, которых я раньше не знал.
Цитата:
Зато получил наконец скрипт - ради чего и рекурсия нужна была, постарался конечно привести его в тот порядок сейчас вот как ты расписывал. Так вот Он выполняет обработку ярлыков в каждой папке и заменяет их пути на относительные. Мне это понадобилось т.к. у меня есть диски на которых есть система из сотен ярлыков, но они становятся не рабочими как только меняешь расположение диска, например подключаешь к другому компьютеру. Так вот теперь мои ярлыки будут заменены очень быстро, а работать будут на любом компьютере с системой Windows конечно. Вот весь код: var wsh = WScript.CreateObject("WScript.Shell"); if( ! /cscript\.exe$/i.test( WScript.FullName ) ) { // проверить что запущено в консольном режиме wsh.Run("cmd /c cscript " + WScript.ScriptName ); // если нет, перезапустить в консоли WScript.Quit(0); // и завершить текущую инкарнацию (пусть работает перезапущенный в консоли) } var kollnk = 0; var fso = WScript.CreateObject("Scripting.FileSystemObject"); // lnk( fso.GetFolder(wsh.CurrentDirectory) ) // запускаем изменение ярлыков для текущей папки т.к. она не обрабатывалась sFolders(fso.GetFolder(wsh.CurrentDirectory)); // запускаем рекурсию для текущей дирректории WScript.Echo("Все готово! Количество обработанных ярлыков = " + kollnk); WScript.Sleep(999000); function sFolders(dirfld) { for( var seq = new Enumerator(dirfld.SubFolders); !seq.atEnd(); seq.moveNext()) { //WScript.Echo( seq.item().path ); lnk( seq.item() ); sFolders( seq.item() ); } } function lnk(dirlnk) // Функция замены свойств ярлыка для относительного пути. { WScript.Echo(dirlnk); // Вывод Папки которая обрабатывается в данный момент var count2 = ( dirlnk.path.split('\\').length - 1 ); //27 считаем количество вхождений косой черты в адресе текущей папки var strNew = ""; // формируем переменную для подстановки и запускаем цикл while ( count2 > 0 ) {strNew = strNew + "..\\"; count2 = count2 - 1;} // сформирует относительный путь for ( var colFiles = new Enumerator (dirlnk.Files); !colFiles.atEnd(); colFiles.moveNext()) // Цикл по всем файлам в { if (colFiles.item().Name.length-colFiles.item().Name.lastIndexOf(".lnk")-4==0) // Если проверяемый файл - ярлык { // тогда var wshShell = WScript.CreateObject("WScript.Shell"); // Создаем новый объект ВСШ для доступа к файлу var oShellLink = wshShell.CreateShortcut(dirlnk.path + "\\" + colFiles.item().Name); // Открываем свойства ярлыка if (oShellLink.TargetPath.split('explorer.exe').length!=2) // Если текущий ярлык еще не был переделан... { // тогда переделываем его: var strPath = oShellLink.TargetPath.substring(3);// 1) Сохраняем изначальный путь без Диска двоиточия и косой черты oShellLink.TargetPath = '%windir%\\explorer.exe'; // 2) заменяем старое имя на имя файла проводника Windows. oShellLink.Arguments = '"' + strNew + strPath + '"' // 3) Вместо старого Записываем новый адрес oShellLink.WorkingDirectory = ""; // 4) В свойствах ярлыка Рабочая папка должна быть пустой oShellLink.Save(); // 5) Сохраняем ярлык с измененными свойствами. kollnk = kollnk + 1;// 6) Считаем кол-во обработанных ярлыков. } } } } |
........................... function sFolders(dirfld) { lnk(dirfld); for( var seq = new Enumerator(dirfld.SubFolders); !seq.atEnd(); seq.moveNext()) { //WScript.Echo( seq.item().path ); sFolders( seq.item() ); } } |
Часовой пояс GMT +3, время: 18:17. |