Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Вывод сообщений в cdm от рекурсивной функции (https://javascript.ru/forum/events/36200-vyvod-soobshhenijj-v-cdm-ot-rekursivnojj-funkcii.html)

dmitriymar 09.03.2013 16:48

Цитата:

Сообщение от cyber
dmitriymar, это я знаю, но Тс говорил по Xp и 7,

вобщето я ответил на "знания" дефачки:)

rgl 09.03.2013 18:53

kosmonavtom, во-первых, смените тон. Вам тут никто ничего не обязан, тем не менее стараются помочь кто как может. А задуматься следует вам, напр. над тем, что возможна ситуация, когда кто-то либо не знает ответа на ваш вопрос настолько хорошо, чтобы сходу написать работающий пример, либо просто не имеет времени, но знает, что найти ответ можно в конкретном месте. Он за вас должен там его искать? Что плохого в том, что хотел помочь и порекомендовал книги?
А если у вас мое предложение по поводу запуска не работает, то вы что-то делаете не так, либо (что более вероятно) просто нагло врете. Я этим пользуюсь уже много лет, и под 2000, и под XP, и под семеркой. Ваш же пример у меня при запуске выводит информацию в консоль.
Если бы у вас это не работало, вы, вместо того, чтобы учить других как вести себя на форуме, рассказали бы что именно не работает - не запускается вообще, или запускается и не выводит ничего в консоль.
И что делает простейшая программи в одну строчку, типа:
WScript.Echo( "test" );
если запустить ее
cscript test.js
И что происходит если сказать
cscript //H:cscript
ну и т.д., т.е. вы пытались бы разобраться в вопросе, который вас поначалу интересовал, а не учили бы старожилов форума, на который вы только что пришли, "хорошим манерам"

cyber 09.03.2013 23:19

rgl, так все таки прав, Тс пишет не на js?

rgl 10.03.2013 01:20

Цитата:

Сообщение от cyber (Сообщение 239722)
rgl, так все таки прав, Тс пишет не на js?

Не понял, это вопрос или утверждение?
Если вопрос ко мне, то я уже некоторое время назад понял безуспешность отстаивания своего мнения на форумах, ибо есть форумы про JavaScript в браузерах, и нет форумов про JavaScript вне браузеров. А на тех форумах что есть, побеждают в споре в подобном вопросе большинством, а большинсво заранее уверено в своей правоте и даже не пытается вникнуть в доводы оппонента.
Мое мнение - вы тут готовы друг другу глотки перегрызть в споре о том, JScript и JavaScript - одно и то же или совершенно разные языки. А вопрос то не в сути, а в терминологии, не договорившись что обозначает данный конкретный термин, нельзя спорить применим ли он в каком-то конкретном случае или нет. Если принять по определению, что JavaScript - язык браузеров, то утверждение "вре браузеров JavaScript нет" становится тавтологией. А если принять по определению, что JavaScript - это реализация стандарта ECMA-262 от фирмы Netscape, то тот язык, что в IE и в опере - уже не JavaScript. Назовем термином xerox только агрегаты, выпущенные одноименной фирмой, и копировальный аппарат, стоящий в соседней комнате - никакой не ксерокс.
Я же склонен называть термином JavaScript язык, соответствующий всем известному стандарту, в котором ничего не говорится про браузер, про объектную модель документа.
Это принято называть базовым JavaScript, и микрософтовский JScript несомненно таковым является. Когда мы добавляем объекты браузера и документа, это уже клиентский JavaScript, но мне такое название не нравится и вот почему - все конструкции языка - простые операторы, циклы, условные операторы, функции, объекты и массивы, регулярные выражения - все это определено в базовом языке, клиентский же - это объекты документа, с которыми можно работать на JavaScript, но (иногда) можно и на VBScript, т.е. это уже находится вне языка, а язык (тот, который есть) имеет к этому доступ. Поэтому я под JavaScript понимаю именно базовый язык, а название JScript говорит не о том, что это "совсем другой язык, не имеющий ничего общего" а о войне терминов.

rgl 10.03.2013 01:23

kosmonavtom, закралось подозрение, может скрипт отрабатывает так быстро, что вы просто не успеваете увидеть консоль? Тогда попробуйте вставить в конце своего скрипта что-то вроде:
WScript.Sleep(5000);

kosmonavtom 10.03.2013 10:14

rgl,
1) Ну понятно, спасибо за разъяснения. Просто обычно люди общаются на форуме и приходят к какому -то решению конструктивному. А тут что-то все ругаются вместо изучения.

2) нет на самом деле я пишу команду script в cmd? а у меня выдается, что мул "script" не является внутренней или внешней командой, исполняемой программой или пакетным файлом. Может что-то не так и не туда написал?

deff, речь о том, что я и не просил ни у кого "сигарет" нет возможности реально подсказать, так лучше вообще ничего не пишите в теме.

rgl 10.03.2013 11:58

Цитата:

Сообщение от kosmonavtom (Сообщение 239756)
rgl, 2) нет на самом деле я пишу команду script в cmd? а у меня выдается, что мул "script" не является внутренней или внешней командой, исполняемой программой или пакетным файлом. Может что-то не так и не туда написал?


Запустить скрипт можно несколькими способами. Не все, но существенные для обсуждаемого вопроса способы:

wscript filename.js
(буковка W вначале очень важна) в этом случае, если в скрипте есть команды Echo, они будут выводить информацию в модальное окно и заставлять кликать мышкой.

cscript filename.js
(буковка c в начале тоже необходима)
в этом случае, во-первых, команда echo будет выводить информацию на консоль, но кроме того появляется более продвинуная возможность писать в stdout и stderr а также читать из stdin

и наконец, можно просто набрать имя файла
test.js
в этом случае скрипт запустится одним из двух вышеупомянутых способов, каким именно - зависит от настроек операционки. Поменять данную настройку операционки проще всего с помощью команд
cscript //H:cscript
cscript //H:wscript

если набрать
cscript
без параметров, можно почитать коротенький хэлп

kosmonavtom 13.03.2013 16:27

спасибо за подсказку. Все получилось :) вот теперь как это выглядит:

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]);
		
		}
	
	}
 
}

kosmonavtom 13.03.2013 16:30

О! только у меня закралось подозрение, что скрипт выполняется два раза :( один раз просто при запуске, а второй раз при запуске через cmd. - ну ладно подумаю еще доработаю - самое главное он информацию выводит в cmd )))

rgl 13.03.2013 16:47

Цитата:

Сообщение от kosmonavtom (Сообщение 240426)
О! только у меня закралось подозрение, что скрипт выполняется два раза :( один раз просто при запуске, а второй раз при запуске через 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); // и завершить текущую инкарнацию (пусть работает перезапущенный в консоли)
}

kosmonavtom 13.03.2013 17:02

rgl, внутри скрипта это нужно, чтобы пользователь щелкнул на единственный файл, а не запускал лишние консоли и прочее. И я думаю он не будет большее количество раз выполняться ведь именно для этого там и стоит if ...

cyber 13.03.2013 17:10

kosmonavtom, а почему и именно скриптовый язык, почему бы не воспользоваться тем же C# он не на много сложнее, проблема в размере файла?

rgl 13.03.2013 17:13

kosmonavtom,
Смотрите мое поправленное предыдущее сообщение

cyber,
этот язык уже есть, есть всегда и у всех (под Windows, разумеется) а всякие там C#, перлы и питоны нужно устанавливать, что не всегда хочется, и не всегда возможно.

rgl 13.03.2013 17:17

Цитата:

Сообщение от kosmonavtom (Сообщение 240444)
rgl, внутри скрипта это нужно, чтобы пользователь щелкнул на единственный файл, а не запускал лишние консоли и прочее. И я думаю он не будет большее количество раз выполняться ведь именно для этого там и стоит if ...

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

kosmonavtom 13.03.2013 17:50

rgl, спасибо за новое условие :) - не знал раньше о таких вещах. А вот код в итоге работает еще и без моего условия и без повторного перезапуска, а просто с двумя строками вначале следующего вида:
var wsh = new ActiveXObject("WScript.Shell");
var cmd = wsh.Exec("cmd /c cscript //H:cscript"); // Перенастройка системы на консольный режим работы

и это я так понимаю самое простое решение для моей рекурсии. Но твое условие я все же думаю оставить в коде т.к. мало ли будут пользователи у которых не успеет консольный режим включиться.

Конечный вариант пока посмотрю на всех машинах, а потом выложу в тему.

rgl 13.03.2013 18:07

Цитата:

Сообщение от kosmonavtom (Сообщение 240472)
rgl, спасибо за новое условие :) - не знал раньше о таких вещах.

Все очень просто, на порядок проще чем объекты html-ного документа, но только если знать, где брать информацию. Всезнающий гугл тут не сильно помогает.

Цитата:

Сообщение от kosmonavtom (Сообщение 240472)
А вот код в итоге работает еще и без моего условия и без повторного перезапуска, а просто с двумя строками вначале следующего вида:
var wsh = new ActiveXObject("WScript.Shell");
var cmd = wsh.Exec("cmd /c cscript //H:cscript"); // Перенастройка системы на консольный режим работы

cscript //H:cscript во-первых, не дает 100% гарантии. У пользователя может просто не хватать прав. А во-вторых, если можно ничего не менять на компьютере пользователя, то лучше не менять, мало ли где еще это может использоваться.

Да, и в моем варианте лучше чуть-чуть подправить:
if( ! /cscript\.exe$/i.test( WScript.FullName ) ) { // проверить что запущено в консольном режиме
(Добавить буковку i, чтобы было нечувствительно к регистру)

kosmonavtom 13.03.2013 18:17

rgl,
Цитата:

cscript //H:cscript во-первых, не дает 100% гарантии. У пользователя может просто не хватать прав. А во-вторых, если можно ничего не менять на компьютере пользователя, то лучше не менять, мало ли где еще это может использоваться.
я тоже думал о том, что лучше ничего не менять в настройках, но надо сказать что на 7-ке у ограниченного правами пользователя все нормально меняется! Ну ладно погоняю пока этот код, а потом примем решение...

kosmonavtom 18.03.2013 18:06

В процессе эксплуатации возникла новая фишка. Теперь оказалось, что если рекурсия натыкается на папку к которой у пользователя нет доступа, то он вылетает. Для исправления ситуации и продолжения работы скрипта, не глядя на эту папку, я решил добавить условие вида: 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 18.03.2013 18:28

Цитата:

Сообщение от kosmonavtom (Сообщение 241393)
if (path.StdErr == 0) // КАК проверить будет ли ошибка у этой папки????

Что вы хотите этим проверить? Что такое path? Кажется, это строковая переменная (глобальная), она, во-первых, никак не связана с проверяемой сейчас папкой, а все время постоянна, а во-вторых, у нее нет свойства StdErr

kosmonavtom 19.03.2013 10:13

rgl, спасибо. Значит я так понял что мне нужно:
1) Поставить строку проверки читабельности папки между 37 и 38 т.к. например системную папку лучше и не записывать в массив записанных адресов тогда вообще.
2) Проверять seq.item().path - но не получается, может не правильно указываю свойства?! Ввести вместо vsePapki[nomerZapisi] еще одну переменную и у нее свойства проверить?! - выберу когда свойства папок найду.
3) И проверить системная ли эта папка? или же есть ли у пользователя к ней доступ? - что-то вроде этого.
Только как? Ладно будем искать... но пока погуглю свойства папки наверно.

rgl 19.03.2013 15:10

Вместо того, чтобы пытаться с помощью форума исправить найденный непонятногде говнокод, лучше было бы это время и усилия потратить на то, чтобы разобраться в теме и написать нормально самому.
Мои замечания к приведенному коду:
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() )
	}
}

kosmonavtom 22.03.2013 19:30

rgl, Вот это спасибо! Вот это КПД :victory: Спасибо за разъяснения, спасибо за помощь. Отдельное спасибо за замечания и абсолютно новые вещи, которых я раньше не знал.
Цитата:

Сообщение от rgl
Вместо того, чтобы пытаться с помощью форума исправить найденный непонятногде говнокод, лучше было бы это время и усилия потратить на то, чтобы разобраться в теме и написать нормально самому.

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

Зато получил наконец скрипт - ради чего и рекурсия нужна была, постарался конечно привести его в тот порядок сейчас вот как ты расписывал. Так вот Он выполняет обработку ярлыков в каждой папке и заменяет их пути на относительные. Мне это понадобилось т.к. у меня есть диски на которых есть система из сотен ярлыков, но они становятся не рабочими как только меняешь расположение диска, например подключаешь к другому компьютеру. Так вот теперь мои ярлыки будут заменены очень быстро, а работать будут на любом компьютере с системой 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) Считаем кол-во обработанных ярлыков.
				} 
      		} 
   	}
}

rgl 23.03.2013 20:04

lnk( fso.GetFolder(wsh.CurrentDirectory) ) // запускаем изменение ярлыков для текущей папки т.к. она не обрабатывалась
...........................
function sFolders(dirfld) {
lnk(dirfld);
for( var seq = new Enumerator(dirfld.SubFolders); !seq.atEnd(); seq.moveNext()) {
//WScript.Echo( seq.item().path );
lnk( seq.item() );
sFolders( seq.item() );
}
}


Часовой пояс GMT +3, время: 18:17.