<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; JScript/VBScript: WSH интерпретатор]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=7766&amp;type=atom" />
	<updated>2020-02-28T23:19:12Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=7766</id>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=138152#p138152" />
			<content type="html"><![CDATA[<p>Достаточно много прошло времени и я вернулся к этому проекту. Задачи прежние:<br />-- реализация <a href="https://ru.wikipedia.org/wiki/REPL">REPL</a> без привлечения сторонних утилит, то есть внутренними средствами самого интерпретатора<br />-- в некоторой степени приблизить JS/VBS/WSH к определенным возможностям современных интерпретаторов (NodeJS, Rhino, Chakra)</p><p>Конечно, NodeJS с его крутыми возможностями значительно выигрывает даже по сравнению с такими крупными аналогами как Rhino (JS, написанный на Java) или Chakra (родная реализация от Microsoft, но все еще внешняя утилита, устанавливаемая вручную).</p><p>Предыдущий скрипт был выполнен как гибрид cmd+js, создающий временный wsf-файл, который затем и исполнялся. Здесь я решил немного изменить подход и сделал гибрид cmd+wsf, который сам же все и исполняет. В результате получилось что-то весьма забавное -- js-код, который исполняет js- или vbs-код. Но здесь я добавил несколько дополнительных полезных &quot;плюшек&quot;, включил поддержку стандартных команд типа <strong>require(&quot;...&quot;)</strong> и <strong>console.log(...)</strong>. Получилось неплохо. При этом &quot;научил&quot; загружать vbs-код. </p><p>На будущее хотелось бы реализовать автоматическое раскрытие файловых шаблонов (file globbing), поддержку файла аргументов, REPL для VBS, сборку автономных скриптов js/vbs/wsf/bat, возможность &quot;компилировать&quot; команды в wsc-файл.</p><p>В настоящее время проект лежит на гитхабе <a href="https://github.com/ildar-shaimordanov/jsxt">https://github.com/ildar-shaimordanov/jsxt</a>. Вполне возможно, когда Chakra станет по умолчанию встроенной, я перестану заниматься им.</p><p>Сейчас несколько примеров</p><p>Посчитать количество строк в каждом файле и в конце вывести суммарный результат (аналог юниксовой команды <strong>wc -l</strong>:<br /></p><div class="codebox"><pre><code>
rem реализация на JS
wsx /n /endfile:&quot;echo(FLN, FILE)&quot; /end:&quot;echo(LN)&quot; ...

rem реализация на VBS
wsx /n /endfile:vbs:&quot;echo FLN, FILE&quot; /end:vbs:&quot;echo LN&quot; ...
</code></pre></div><p>Пронумеровать строки (аналогично юниксовой команде <strong>cat -bn</strong>):<br /></p><div class="codebox"><pre><code>
rem реализация на JS
wsx /p /e:&quot;LINE = LN + &#039;:&#039; + LINE&quot; ...

rem реализация на VBS
wsx /let:delim=&quot;:&quot; /p /e:vbs:&quot;LINE = LN &amp; delim &amp; LINE&quot; ...
</code></pre></div><p>Распечатать первые 10 строк (аналог юникосвой команды <strong>head -10</strong>):<br /></p><div class="codebox"><pre><code>
rem реализация на JS
wsx /let:limit=10 /p /e:&quot;LN &gt; limit &amp;&amp; quit()&quot;

rem реализация на VBS
wsx /use:vbs /let:limit=10 /p /e:&quot;if LN &gt; limit then exit : end if&quot;
</code></pre></div><p>Обоснованная критика -- принимается, предложения -- обсуждаются, улучшения -- приветствуются. А здесь полный текст скрипта <strong>wsx.bat</strong>:</p><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header"><strong>+</strong>&nbsp;полный текст скрипта &quot;wsx.bat&quot;</div><div class="fancy_spoiler"><div class="codebox"><pre><code>
&lt;?xml :
: version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;&lt;!--
@echo off
cscript //nologo &quot;%~f0?.wsf&quot; %*
goto :EOF
: --&gt;

&lt;package&gt;
&lt;job id=&quot;wsx&quot;&gt;
&lt;?job error=&quot;false&quot; debug=&quot;false&quot; ?&gt;

&lt;script language=&quot;javascript&quot;&gt;&lt;![CDATA[

var NAME    = &#039;WSX&#039;;
var VERSION = &#039;1.0.1 Alpha&#039;;

]]&gt;&lt;/script&gt;

&lt;runtime&gt;
&lt;description&gt;&lt;![CDATA[
WSX: Version 1.0.1 Alpha
Copyright (C) 2009-2015, 2019, 2020 Ildar Shaimordanov

Run an external script file in the same way as it can be done traditionally via &quot;cscript&quot; or &quot;wscript&quot; with additional benefits making its usage closer to NodeJS, Perl, Python etc.

Run itself in the interactive mode. Type in the prompt any JS or VBS commands and execute them immediately. In this mode each entered line is evaluated immediately. To enable many lines executed as one you need to surround them with the double colons &quot;::&quot;. The first double colon turns on the multiline mode, the second one turns it off. After that everything entered will be executed.

Run one line program from CLI and apply it on inputstream and other files. One line programs allow to estimate some code on the fly, without creating a temporary file. Writing one line programs you focus on the most important parts of the program implementation. Some implementation stuff -- like objects initialization, I/O operations etc -- are hidden on your eyes, however executed yet implicitly.

If the tool is launched with the one line program, everything after is assumed as a file name. Each argument is opened as a file and processed line by line until the end of file. Otherwise, if no any one line program is entered, the first item of the argument list is the script file and the rest of arguments are arguments for the script file. They could be everything and the script can use them accordingly its functionality.

For more convenience there are few predefined global definitions:

Common objects:

FSO     - The object &quot;Scripting.FileSystemObject&quot;
STDIN   - The reference to &quot;WScript.StdIn&quot;
STDOUT  - The reference to &quot;WScript.StdOut&quot;
STDERR  - The reference to &quot;WScript.StdErr&quot;

Common helper functions:

usage(), help()          - Display this help
echo(), print(), alert() - Print expressions
quit(), exit()           - Quit this shell
cmd(), shell()           - Run a command or DOS-session
sleep(n)                 - Sleep n milliseconds
clip()                   - Read from or write to clipboard
gc()                     - Run the JScript garbage collector

ERROR   - The variable keeping the last error
USE     - The instance of &quot;Importer&quot; class to import VBS easier
ARGV    - The CLI arguments

Used in the loop mode:

STREAM  - The reference to the stream of the current file
FILE    - The name of the current file
FILEFMT - The format to open files (&quot;ascii&quot;, &quot;unicode&quot; or system &quot;default&quot;)
LINE    - The current line
FLN     - The line number in the current file
LN      - The total line number

These special functions can be used on the loop mode only to cover the issue when we can&#039;t use &quot;continue&quot; and &quot;break&quot;.

next()  - The &quot;continue&quot; operator
last()  - The &quot;break&quot; operator

Used in REPL:

The interactive mode provides the following useful properties for referencing to the history of the commands and REPL mode:

REPL.number  - the current line number
REPL.history - the list of all commands entered in the current session
REPL.quiet   - the current session mode

The CLI options supplying the program parts for execution could be infixed with the engine identifier (&quot;js&quot; or &quot;vbs&quot;) supposed to be used for processing these options. See examples below.

The name explanation:

Following the old good tradition to explain acronyms recursively &quot;WSX&quot; means &quot;WSX Simulates eXecutable&quot;.

]]&gt;&lt;/description&gt;
&lt;example&gt;&lt;![CDATA[
Examples:

- Run interactively:
  wsx

- Count the number of lines (similar to &quot;wc -l&quot;, the unix tool):
  wsx /n /endfile:&quot;echo(FLN, FILE)&quot; /end:&quot;echo(LN)&quot;
  wsx /n /endfile:vbs:&quot;echo FLN, FILE&quot; /end:vbs:&quot;echo LN&quot;
  wsx /use:vbs /n /endfile:&quot;echo FLN, FILE&quot; /end:&quot;echo LN&quot;

- Numerate lines of each input file (VScript example shows how to bypass the trouble with quotes within quotes):
  wsx /p /e:&quot;LINE = LN + &#039;:&#039; + LINE&quot;
  wsx /let:delim=&quot;:&quot; /p /e:vbs:&quot;LINE = LN &amp; delim &amp; LINE&quot;

- Print first 10 lines (similar to &quot;head&quot;, the unix tool):
  wsx /let:limit=10 /p /e:&quot;LN &gt; limit &amp;&amp; quit()&quot;
  wsx /use:vbs /let:limit=10 /p /e:&quot;if LN &gt; limit then exit : end if&quot;

- Print last 10 lines (similar to &quot;tail&quot;, the unix tool):
  wsx /let:limit=10 /n /beginfile:&quot;lines=[]&quot; /e:&quot;lines.push(LINE); lines.length &gt; limit &amp;&amp; lines.shift()&quot; /endfile:&quot;echo(lines.join(&#039;\n&#039;))&quot;
]]&gt;&lt;/example&gt;
&lt;named
	name=&quot;help&quot;
	helpstring=&quot;Print this help and exit (&amp;#34;/h&amp;#34; shortcut)&quot;
	type=&quot;simple&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;version&quot;
	helpstring=&quot;Print version information and exit&quot;
	type=&quot;simple&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;dry-run&quot;
	helpstring=&quot;Show in pseudocode what is going to be executed&quot;
	type=&quot;simple&quot;
	required=&quot;false&quot;
	/&gt;
&lt;!--
&lt;named
	name=&quot;compile&quot;
	helpstring=&quot;Compile and store to another file without execution&quot;
	type=&quot;simple&quot;
	required=&quot;false&quot;
	/&gt;
--&gt;
&lt;named
	name=&quot;quiet&quot;
	helpstring=&quot;Be quiet in the interactive mode (&amp;#34;/q&amp;#34; shortcut)&quot;
	type=&quot;simple&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;use&quot;
	helpstring=&quot;Use the engine (&amp;#34;js&amp;#34; or &amp;#34;vbs&amp;#34;)&quot;
	type=&quot;string&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;m&quot;
	helpstring=&quot;Load the module (similar to &amp;#34;require(...)&amp;#34; in NodeJS)&quot;
	type=&quot;string&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;let&quot;
	helpstring=&quot;Assign the value: &amp;#34;name=value&amp;#34;&quot;
	type=&quot;string&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;set&quot;
	helpstring=&quot;Create the object: &amp;#34;name=CreateObject(object)&amp;#34;&quot;
	type=&quot;string&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;get&quot;
	helpstring=&quot;Get the object: &amp;#34;name=GetObject(object)&amp;#34;&quot;
	type=&quot;string&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;e&quot;
	helpstring=&quot;One line program (multiple &amp;#34;/e&amp;#34;&#039;s supported)&quot;
	type=&quot;string&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;n&quot;
	helpstring=&quot;Apply a program in a loop &amp;#34;while read LINE { ... }&amp;#34;&quot;
	type=&quot;simple&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;p&quot;
	helpstring=&quot;Apply a program in a loop &amp;#34;while read LINE { ... print }&amp;#34;&quot;
	type=&quot;simple&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;begin&quot;
	helpstring=&quot;The code for executing before the loop&quot;
	type=&quot;string&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;end&quot;
	helpstring=&quot;The code for executing after the loop&quot;
	type=&quot;string&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;beginfile&quot;
	helpstring=&quot;The code for executing before each file&quot;
	type=&quot;string&quot;
	required=&quot;false&quot;
	/&gt;
&lt;named
	name=&quot;endfile&quot;
	helpstring=&quot;The code for executing after each file&quot;
	type=&quot;string&quot;
	required=&quot;false&quot;
	/&gt;
&lt;unnamed
	name=&quot;scriptfile&quot;
	helpstring=&quot;The script file&quot;
	required=&quot;false&quot;
	/&gt;
&lt;!--
&lt;named
	name=&quot;@&quot;
	helpstring=&quot;Read arguments from the specified file&quot;
	type=&quot;string&quot;
	required=&quot;false&quot;
	/&gt;
--&gt;
&lt;named
	name=&quot;f&quot;
	helpstring=&quot;Open a file as &amp;#34;ascii&amp;#34;, &amp;#34;unicode&amp;#34; or using system &amp;#34;default&amp;#34;&quot;
	type=&quot;string&quot;
	required=&quot;false&quot;
	/&gt;
&lt;unnamed
	name=&quot;arguments&quot;
	helpstring=&quot;Other arguments to be passed to the program&quot;
	required=&quot;false&quot;
	/&gt;
&lt;/runtime&gt;

&lt;!-- &lt;script language=&quot;javascript&quot; src=&quot;./wsx/Helpers.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script language=&quot;javascript&quot;&gt;&lt;![CDATA[
//
// Set of useful and convenient definitions
// This script is the part of the wsx
//
// Copyright (c) 2019, 2020 by Ildar Shaimordanov
//

var FSO = new ActiveXObject(&#039;Scripting.FileSystemObject&#039;);

var STDIN = WScript.StdIn;
var STDOUT = WScript.StdOut;
var STDERR = WScript.StdErr;

var usage = help = (function() {
	var helpMsg = [
		  &#039;Commands                 Descriptions&#039;
		, &#039;========                 ============&#039;
		, &#039;usage(), help()          Display this help&#039;
		, &#039;echo(), print(), alert() Print expressions&#039;
		, &#039;quit(), exit()           Quit this shell&#039;
		, &#039;cmd(), shell()           Run a command or DOS-session&#039;
		, &#039;sleep(n)                 Sleep n milliseconds&#039;
		, &#039;clip()                   Read from or write to clipboard&#039;
		, &#039;gc()                     Run the JScript garbage collector&#039;
	].join(&#039;\n&#039;);

	return function() {
		WScript.Echo(helpMsg);
	};
})();

var echo = print = alert = (function() {
	var slice = Array.prototype.slice;

	return function() {
		WScript.Echo(slice.call(arguments));
	};
})();

var quit = exit = function(exitCode) {
	WScript.Quit(exitCode);
};

var cmd = shell = function(command) {
	var shell = new ActiveXObject(&#039;WScript.Shell&#039;);
	shell.Run(command || &#039;%COMSPEC%&#039;);
};

var sleep = function(time) {
	return WScript.Sleep(time);
};

var clip = function(text) {
	if ( typeof text == &#039;undefined&#039; ) {
		return new ActiveXObject(&#039;htmlfile&#039;).parentWindow.clipboardData.getData(&#039;Text&#039;);
	}

	// Validate a value is integer in the range 1..100
	// Otherwise, defaults to 20
	var clamp = function(x) {
		x = Number(x);
		if ( isNaN(x) || x &lt; 1 || x &gt; 100 ) {
			x = 20;
		}
		return x;
	};

	var WAIT1 = clamp(clip.WAIT_READY);
	var WAIT2 = clamp(clip.WAIT_LOADED);

	// Borrowed from https://stackoverflow.com/a/16216602/3627676
	var msie = new ActiveXObject(&#039;InternetExplorer.Application&#039;);
	msie.silent = true;
	msie.Visible = false;
	msie.Navigate(&#039;about:blank&#039;);

	// Wait until MSIE ready
	while ( msie.ReadyState != 4 ) {
		WScript.Sleep(WAIT1);
	}

	// Wait until document loaded
	while ( msie.document.readyState != &#039;complete&#039; ) {
		WScript.Sleep(WAIT2);
	}

	msie.document.body.innerHTML = &#039;&lt;textarea id=&quot;area&quot; wrap=&quot;off&quot; /&gt;&#039;;
	var area = msie.document.getElementById(&#039;area&#039;);
	area.value = text;
	area.select();
	area = null;

	// 12 - &quot;Edit&quot; menu, &quot;Copy&quot; command
	//  0 - the default behavior
	msie.ExecWB(12, 0);
	msie.Quit();
	msie = null;
};

var gc = CollectGarbage;

if ( typeof exports != &quot;undefined&quot; ) {
	exports.FSO = FSO;
	exports.STDIN = STDIN;
	exports.STDOUT = STDOUT;
	exports.STDERR = STDERR;

	exports.usage = usage;
	exports.help = help;

	exports.echo = echo;
	exports.alert = alert;
	exports.print = print;

	exports.quit = quit;
	exports.exit = exit;

	exports.cmd = cmd;
	exports.shell = shell;

	exports.sleep = sleep;
	exports.clip = clip;
	exports.gc = gc;
}
]]&gt;&lt;/script&gt;

&lt;!-- &lt;script language=&quot;javascript&quot; src=&quot;./core/console.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script language=&quot;javascript&quot;&gt;&lt;![CDATA[
//
// console.js
// Imitation of the NodeJS console in the Windows Scripting Host
//
// Copyright (c) 2012, 2013, 2019, 2020 by Ildar Shaimordanov
//

/*

The module adds the useful NodeJS console features to WSH

&quot;console.log(), console.debug(), ...&quot; can be used the same way as used in NodeJS.

Log messages with custom icon depending on the function used.
	console.log(object[, object, ...])
	console.debug(object[, object, ...])
	console.info(object[, object, ...])
	console.warn(object[, object, ...])
	console.error(object[, object, ...])

Test if the expression. If it is false, the info will be logged in the console
	console.assert(expression[, object, ...])

Starts and stops a timer and writes the time elapsed
	console.time(name)
	console.timeEnd(name)

Customizing the console
	console.fn

Checks that the object is a formatting string
	console.fn.isFormat(object)

The simplest formatting function immitating C-like format
	console.fn.format(pattern, objects)

Details for the complex object
	console.fn.inspect(object)

The low-level printing function
	console.fn.print(msgType, msg)

The deep of nestion for complex structures (default is 5)
	console.fn.deep

The initial value of indentation (4 whitespaces, by default).
A numeric value defines indentaion size, the number of space chars.
	console.fn.space

Numeric values controls the visibility of functions. Defaults to 0.
(0 - do not show function, 1 - show [Function] string, 2 - show a details)
	console.fn.func

The visibility properties from the prototype of the oject. Defaults to 0.
(0 - do not show properties from prototype, 1 - show then)
	console.fn.proto

The string to glue the set of arguments when output them
	console.fn.separator = &#039; &#039;

The following functions are not implemented:
	console.clear
	console.count
	console.dir
	console.dirxml
	console.group
	console.groupCollapsed
	console.groupEnd
	console.profile
	console.profileEnd
	console.table
	console.trace

*/

var console = console || (function() {

	var entities = {
		&#039;&amp;&#039;: &#039;&amp;amp;&#039;, 
		&#039;&quot;&#039;: &#039;&amp;quot;&#039;, 
		&#039;&lt;&#039;: &#039;&amp;lt;&#039;, 
		&#039;&gt;&#039;: &#039;&amp;gt;&#039;
	};

	var escaped = /[\x00-\x1F\&quot;\\]/g;
	var special = {
		&#039;&quot;&#039;: &#039;\\&quot;&#039;, 
		&#039;\r&#039;: &#039;\\r&#039;, 
		&#039;\n&#039;: &#039;\\n&#039;, 
		&#039;\t&#039;: &#039;\\t&#039;, 
		&#039;\b&#039;: &#039;\\b&#039;, 
		&#039;\f&#039;: &#039;\\f&#039;, 
		&#039;\\&#039;: &#039;\\\\&#039;
	};

	var space;
	var indent = &#039;&#039;;

	var deep;

	var proto;
	var func;

	function _quote(value) {
		var result = value.replace(escaped, function($0) {
			return special[$0] || $0;
		});
		return &#039;&quot;&#039; + result + &#039;&quot;&#039;;
	};

	// The main method for printing objects
	var inspect = function(object) {
		switch (typeof object) {
		case &#039;string&#039;:
			return _quote(object);

		case &#039;boolean&#039;:
		case &#039;number&#039;:
		case &#039;undefined&#039;:
		case &#039;null&#039;:
			return String(object);

		case &#039;function&#039;:
			if ( func == 1 ) {
				return &#039;[Function]&#039;;
			}
			if ( func &gt; 1 ) {
				return object.toString();
			}
			return &#039;&#039;;

		case &#039;object&#039;:
			if ( object === null ) {
				return String(object);
			}

			// Assume win32 COM objects
			if ( object instanceof ActiveXObject ) {
				return &#039;[ActiveXObject]&#039;;
			}

			var t = Object.prototype.toString.call(object);

			// Assume the RegExp object
			if ( t == &#039;[object RegExp]&#039; ) {
				return String(object);
			}

			// Assume the Date object
			if ( t == &#039;[object Date]&#039; ) {
				return object.toUTCString();
			}

			// Stop the deeper nestings
			if ( ! deep ) {
				return &#039;[...]&#039;;
			}

			var saveDeep = deep;
			deep--;

			var saveIndent = indent;
			indent += space;

			var result = [];
			for (var k in object) {
				if ( ! object.hasOwnProperty(k) &amp;&amp; ! proto ) {
					continue;
				}

				var v;

				if ( object[k] === object ) {
					v = &#039;[Recursive]&#039;;
				} else {
					v = inspect(object[k]);
					if ( v === &#039;&#039; ) {
						// Sure that any property will return non-empty string
						// Only functions can return an empty string when func == 0
						continue;
					}
				}

				result.push(k + &#039;: &#039; + v);
			}

			var pred;
			var post;

			if ( t == &#039;[object Array]&#039; ) {
				pred = &#039;Array(&#039; + object.length + &#039;) [&#039;;
				post = &#039;]&#039;;
			} else {
				pred = &#039;Object {&#039;;
				post = &#039;}&#039;;
			}

			result = result.length == 0 
				? &#039;\n&#039; + saveIndent 
				: &#039;\n&#039; + indent + result.join(&#039;\n&#039; + indent) + &#039;\n&#039; + saveIndent;

			indent = saveIndent;
			deep = saveDeep;

			return pred + result + post;

		default:
			return &#039;[Unknown]&#039;;
		}
	};

	// This regular expression is used to recongnize a formatting string 
	var reFormat = /%%|%(\d+)?([idfxso])/g;

	// Checks that the object is a formatting string
	var isFormat = function(object) {
		return Object.prototype.toString.call(object) == &#039;[object String]&#039; &amp;&amp; object.match(reFormat);
	};

	var formatters = {};
	formatters.i = function(v) { return Number(v).toFixed(0); };
	formatters.d = 
	formatters.f = function(v) { return Number(v).toString(10); };
	formatters.x = function(v) { return Number(v).toString(16); }, 
	formatters.o = inspect;
	formatters.s = function(v) { return String(v); };

	// The formatting function immitating C-like &quot;printf&quot;
	var format = function(pattern, objects) {
		var i = 0;
		return pattern.replace(reFormat, function(format, width, id) {
			if ( format == &#039;%%&#039; ) {
				return &#039;%&#039;;
			}

			i++;

			var r = formatters[id](objects[i]);

			return r;
		});
	};

	// The low-level printing function
	var print = function(msgType, msg) {
		WScript.Echo(msg);
	};


	// The core function
	var printMsg = function(msgType, objects) {
		// Get the actual configuration of the console
		var fn = console.fn || {};

		var sep = fn.separator || &#039; &#039;;

		space = fn.space;
		deep = Number(fn.deep) &gt; 0 ? fn.deep : 5;
		proto = fn.proto || 0;
		func = fn.func || 0;

		var t = Object.prototype.toString.call(space);
		if ( t == &#039;[object Number]&#039; &amp;&amp; space &gt;= 0 ) {
			space = new Array(space + 1).join(&#039; &#039;);
		} else if ( t != &#039;[object String]&#039; ) {
			space = &#039;    &#039;;
		}

		if ( typeof fn.isFormat == &#039;function&#039; ) {
			isFormat = fn.isFormat;
		}
		if ( typeof fn.format == &#039;function&#039; ) {
			format = fn.format;
		}
		if ( typeof fn.inspect == &#039;function&#039; ) {
			inspect = fn.inspect;
		}
		if ( typeof fn.print == &#039;function&#039; ) {
			print = fn.print;
		}

		var result;

		if ( isFormat(objects[0]) ) {
			//result = format(objects[0], Array.prototype.slice.call(objects, 1));
			result = format(objects[0], objects);
		} else {
			result = [];
			for (var i = 0; i &lt; objects.length; i++) {
				result.push(inspect(objects[i]));
			}
			result = result.join(sep);
		}

		print(msgType, result);
	};


	var log = function() {
		printMsg(0, arguments);
	};

	var debug = log;

	var info = function() {
		printMsg(64, arguments);
	};

	var warn = function() {
		printMsg(48, arguments);
	};

	var error = function() {
		printMsg(16, arguments);
	};


	// If the expression is false, the rest of arguments will be logged in 
	// the console
	var assert = function(expr) {
		if ( expr ) {
			return;
		}
		error.apply(console, arguments.length &lt; 2 ? [&#039;Assertion error&#039;] : Array.prototype.slice.call(arguments, 1));
	};


	// Processing of timers start/stop
	var timeNames = {};

	var timeStart = function(name) {
		if ( ! name ) {
			return;
		}

		timeNames[name] = new Date();
		log(name + &#039;: Timer started&#039;);
	};

	var timeEnd = function(name) {
		if ( ! name || ! timeNames.hasOwnProperty(name) ) {
			return;
		}

		var t = new Date() - timeNames[name];
		delete timeNames[name];

		log(name + &#039;: &#039; + t + &#039;ms&#039;);
	};


	return {
		// Implemented methods
		log: log, 
		debug: debug, 
		info: info, 
		warn: warn, 
		error: error, 

		assert: assert, 

		time: timeStart, 
		timeEnd: timeEnd, 

		// Not implemented methods
		clear: function() {}, 

		dir: function() {}, 
		dirxml: function() {}, 

		group: function() {}, 
		groupCollapsed: function() {}, 
		groupEnd: function() {}, 

		profile: function() {}, 
		profileEnd: function() {}, 

		table: function() {}, 

		trace: function() {}, 

		// Customizing the console
		fn: {
			space: 4,
			deep: 5,
			proto: 0,
			func: 0,
			separator: &#039; &#039;
		}
	};

})();

if ( typeof module != &quot;undefined&quot; ) {
	module.exports = console;
}
]]&gt;&lt;/script&gt;

&lt;!-- &lt;script language=&quot;javascript&quot; src=&quot;./core/require.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script language=&quot;javascript&quot;&gt;&lt;![CDATA[
//
// require.js
// Imitation of the NodeJS function require in the Windows Scripting Host
//
// Copyright (c) 2019, 2020 by Ildar Shaimordanov
//

/*

The module adds to WSH the &quot;require&quot; function, the useful NodeJS feature, and some additional extensions.

Load a module by name of filename
	require(id[, options])

Resolve a location of the module
	require.resolve(id[, options])

The list of of paths used to resolve the module location
	require.paths

Cache for the imported modules
	require.cache

*/

var require = require || (function() {

	var fso = WScript.CreateObject(&quot;Scripting.FileSystemObject&quot;);

	function loadFile(file, format) {
		var stream = fso.OpenTextFile(file, 1, false, format || 0);
		var text = stream.ReadAll();
		stream.Close();

		return text;
	};

	/**
	 * Load a module by name of filename
	 *
	 * @param	&lt;String&gt;	module name or path
	 * @param	&lt;Object&gt;	options
	 * @return	&lt;Object&gt;	exported module content
	 *
	 * Available options:
	 * - paths	&lt;Array&gt;		Paths to resolve the module location
	 * - format	&lt;Integer&gt;	format of the opened file (-2 - system default, -1 - Unicode file, 0 - ASCII file)
	 */
	function require(id, options) {
		if ( ! id ) {
			throw new TypeError(&quot;Missing path&quot;);
		}

		if ( typeof id != &quot;string&quot; ) {
			throw new TypeError(&quot;Path must be a string&quot;);
		}

		options = options || {};

		var file = require.resolve(id, options);

		require.cache = require.cache || {};

		if ( ! require.cache[file] || ! require.cache[file].loaded ) {
			var text = loadFile(file, options.format);

			var code
				= &quot;(function(module) {\n&quot;
				+ &quot;var exports = module.exports;\n&quot;
				+ text + &quot;;\n&quot;
				+ &quot;return module.exports;\n&quot;
				+ &quot;})({ exports: {} })&quot;;

			var evaled = eval(code);

			require.cache[file] = {
				exports: evaled,
				loaded: true
			};
		}

		return require.cache[file].exports;
	};

	function absolutePath(file) {
		if ( fso.FileExists(file) ) {
			return fso.GetAbsolutePathName(file);
		}
	}

	/**
	 * Resolve a location of the module
	 *
	 * @param	&lt;String&gt;	module name or path
	 * @param	&lt;Object&gt;	options
	 * @return	&lt;String&gt;	resolved location of the module
	 *
	 * Available options:
	 * - paths	&lt;Array&gt;		Paths to resolve the module location
	 */
	require.resolve = function(id, options) {
		options = options || {};

		var file = /[\\\/]|\.js$/i.test(id)

			// module looks like a path
			? absolutePath(/\.[^.\\\/]+$/.test(id) ? id : id + &quot;.js&quot;)

			// attempt to find a librarian module
			: (function() {
				var paths = [].concat(options.paths || [], require.paths);
				for (var i = 0; i &lt; paths.length; i++) {
					var file = absolutePath(paths[i] + &quot;\\&quot; + id + &quot;.js&quot;);
					if ( file ) {
						return file;
					}
				}
			})();

		if ( ! file ) {
			throw new Error(&quot;Cannot find module &#039;&quot; + id + &quot;&#039;&quot;);
		}

		return file;
	};

	var myDir = fso.GetParentFolderName(WScript.ScriptFullName);
	var me = WScript.ScriptName.replace(/(\.[^.]+\?)?\.[^.]+$/, &#039;&#039;);

	var shell = WScript.CreateObject (&quot;WScript.Shell&quot;);
	var cwd = shell.CurrentDirectory;

	require.paths = [
		  myDir + &quot;\\js&quot;
		, myDir + &quot;\\&quot; + me
		, myDir + &quot;\\&quot; + me + &quot;\\js&quot;
		, myDir + &quot;\\lib&quot;
		, cwd
	];

	if ( fso.GetBaseName(myDir) == &quot;bin&quot; ) {
		require.paths.push(myDir + &quot;\\..\\lib&quot;);
	}

	return require;
})();
]]&gt;&lt;/script&gt;
&lt;!-- &lt;script language=&quot;vbscript&quot; src=&quot;./core/importer.vbs&quot;&gt;&lt;/script&gt; --&gt;
&lt;script language=&quot;vbscript&quot;&gt;&lt;![CDATA[
&#039;
&#039; importer.js
&#039; Import modules by name or filename similar to the NodeJS &quot;require&quot;
&#039;
&#039; Copyright (c) 2019, 2020 by Ildar Shaimordanov
&#039;
&#039; @see
&#039; https://blog.ctglobalservices.com/scripting-development/jgs/include-other-files-in-vbscript/
&#039; https://helloacm.com/include-external-files-in-vbscriptjscript-wsh/
&#039; https://www.planetcobalt.net/sdb/importvbs.shtml
&#039; https://stackoverflow.com/a/316169/3627676
&#039; https://stackoverflow.com/a/43957897/3627676
&#039; https://riptutorial.com/vbscript/topic/8345/include-files


&#039; Create and return an instance of the Importer class
&#039; Can be useful to import VBScript modules from JScript
&#039;
&#039; @return	&lt;Importer&gt;
Function CreateImporter
	Set CreateImporter = New Importer
End Function


Class Importer
	&#039; For caching already loaded modules
	Private cache

	&#039; File system object, used internally
	Private fso

	&#039; The list of of paths used to resolve the module location
	Public paths

	&#039; format of the opened file
	&#039; (-2 - system default, -1 - Unicode file, 0 - ASCII file)
	Public format

	&#039; Initialize importer
	Private Sub Class_Initialize
		Set cache = CreateObject(&quot;Scripting.Dictionary&quot;)
		Set fso = CreateObject(&quot;Scripting.FileSystemObject&quot;)

		Dim re
		Set re = New RegExp
		re.Pattern = &quot;(\.[^.]+\?)?\.[^.]+$&quot;

		Dim mydir, myself

		mydir = fso.GetParentFolderName(WScript.ScriptFullName)
		myself = re.Replace(WScript.ScriptName, &quot;&quot;)

		Dim shell, cwd

		Set shell = WScript.CreateObject(&quot;WScript.Shell&quot;)
		cwd = shell.CurrentDirectory

		paths = Array( _
			  mydir &amp; &quot;\vbs&quot; _
			, mydir &amp; &quot;\&quot; &amp; myself _
			, mydir &amp; &quot;\&quot; &amp; myself &amp; &quot;\vbs&quot; _
			, mydir &amp; &quot;\lib&quot; _
			, cwd _
		)
		If fso.GetBaseName(mydir) = &quot;bin&quot; Then
			ReDim Preserve paths(UBound(paths) + 1)
			paths(UBound(paths)) = mydir &amp; &quot;\..\lib&quot;
		End If
	End Sub

	&#039; Destroy importer
	Private Sub Class_Terminate
		Set paths = Nothing
		Set fso = Nothing
		Set cache = Nothing
	End Sub

	Private Sub PathIncrement(insert, apath)
		Dim gain
		If IsArray(apath) Then
			gain = UBound(apath) + 1
		Else
			gain = 1
		End If

		Dim count
		count = UBound(paths)

		Redim Preserve paths(count + gain)

		Dim i

		If insert = 1 Then
			For i = count To 0 Step -1
				paths(i + gain) = paths(i)
			Next
			count = 0
		End If

		If IsArray(apath) Then
			For i = 0 To gain - 1
				paths(count + i) = apath(i)
			Next
		Else
			paths(count) = apath
		End If
	End Sub

	&#039; Add a path or array of paths to the begin of the list of paths
	&#039;
	&#039; @param	&lt;String|Array&gt;	Path or array of paths
	Public Sub PathInsert(apath)
		PathIncrement 1, apath
	End Sub

	&#039; Add a path or array of paths to the end of the list of paths
	&#039;
	&#039; @param	&lt;String|Array&gt;	Path or array of paths
	Public Sub PathAppend(apath)
		PathIncrement 0, apath
	End Sub

	&#039; Load a text
	&#039;
	&#039; @param	&lt;String&gt;	a text to be executed
	Public Sub Execute(text)
		On Error GoTo 0
		ExecuteGlobal text
		On Error Resume Next
	End Sub

	&#039; Load a module by name of filename
	&#039;
	&#039; @param	&lt;String&gt;	module name or path
	Public Sub Import(id)
		On Error GoTo 0

		Dim Name

		Dim ErrStr

		Select Case VarType(id)
		Case vbString
			Name = id
		Case vbEmpty
			ErrStr = &quot;Missing path (Empty)&quot;
		Case vbNull
			ErrStr = &quot;Missing path (Null)&quot;
		Case Else
			ErrStr = &quot;Path must be a string&quot;
		End Select

		If ErrStr &lt;&gt; &quot;&quot; Then
			Err.Description = ErrStr
			Err.Raise vbObjectError
		End If

		Dim file
		file = Resolve(id)

		If Not cache.Exists(file) Then
			Dim text
			text = ReadFile(file)
			ExecuteGlobal text

			cache.Add file, 1
		End If

		On Error Resume Next
	End Sub

	&#039; Read a file
	Private Function ReadFile(file)
		Dim stream
		Set stream = fso.OpenTextFile(file, 1, False, format)
		ReadFile = stream.ReadAll
		stream.Close
		Set stream = Nothing
	End Function

	&#039; Resolve a location of the module
	&#039;
	&#039; @param	&lt;String&gt;	module name or path
	&#039; @return	&lt;String&gt;	resolved location of the module
	Public Function Resolve(id)
		Dim file

		Dim re
		Set re = New RegExp

		re.Pattern = &quot;[\\\/]|\.vbs$&quot;
		re.IgnoreCase = True
		If re.Test(id) Then
			&#039; module looks like a path
			re.Pattern = &quot;\.[^.\\\/]+$&quot;
			If re.Test(id) Then
				file = id
			Else
				file = id &amp; &quot;.vbs&quot;
			End If
			Resolve = AbsolutePath(file)
		Else
			&#039; attempt to load a librarian module
			Dim path
			For Each path In paths
				file = path &amp; &quot;\&quot; &amp; id &amp; &quot;.vbs&quot;
				Resolve = AbsolutePath(file)
				If Resolve &lt;&gt; &quot;&quot; Then
					Exit For
				End If
			Next
		End If

		If Resolve = &quot;&quot; Then
			Err.Description = &quot;Cannot find module &#039;&quot; &amp; id &amp; &quot;&#039;&quot;
			Err.Raise vbObjectError
		End If
	End Function

	&#039; Return the absolute path if file exists, otherwise - empty string
	Private Function AbsolutePath(file)
		AbsolutePath = &quot;&quot;
		If fso.FileExists(file) Then
			AbsolutePath = fso.GetAbsolutePathName(file)
		End If
	End Function

End Class
]]&gt;&lt;/script&gt;

&lt;!-- &lt;script language=&quot;javascript&quot; src=&quot;./wsx/Program.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script language=&quot;javascript&quot;&gt;&lt;![CDATA[
//
// Program
// This script is the part of the wsx
//
// Copyright (c) 2019, 2020 by Ildar Shaimordanov
//

var Program = {
	dryRun: false,
	quiet: false,
	inLoop: 0,

	engine: &quot;js&quot;,

	modules: [],
	vars: [],

	main: [],

	begin: [],
	end: [],
	beginfile: [],
	endfile: [],

	setEngine: function(engine) {
		this.engine = engine;
	},
	getEngine: function(engine) {
		return (engine || this.engine).toLowerCase();
	},

	setMode: function(mode) {
		var loopTypes = { i: 0, n: 1, p: 2 };
		this.inLoop = loopTypes[mode];
	},

	setQuiet: function() {
		this.quiet = true;
	},

	addScript: function(engine, name) {
		name = name.replace(/\\/g, &#039;\\\\&#039;);
		var result = &#039;&#039;;
		if ( this.getEngine(engine) == &quot;vbs&quot; ) {
			result = &#039;USE.Import(&quot;&#039; + name + &#039;&quot;)&#039;;
		} else {
			result = &#039;require(&quot;&#039; + name + &#039;&quot;)&#039;;
		}
		return result;
	},
	addModule: function(engine, name) {
		this.modules.push(this.addScript(engine, name));
	},

	vbsVar: function(name, value, setter) {
		var result = &#039;Dim &#039; + name;
		if ( value ) {
			switch( setter.toLowerCase() ) {
			case &#039;let&#039;: result += &#039; : &#039; + name + &#039; = \\&quot;&#039; + value + &#039;\\&quot;&#039;; break;
			case &#039;set&#039;: result += &#039; : Set &#039; + name + &#039; = CreateObject(\\&quot;&#039; + value + &#039;\\&quot;)&#039;; break;
			case &#039;get&#039;: result += &#039; : Set &#039; + name + &#039; = GetObject(\\&quot;&#039; + value + &#039;\\&quot;)&#039;; break;
			}
		}
		return &#039;USE.Execute(&quot;&#039; + result + &#039;&quot;)&#039;;
	},
	jsVar: function(name, value, setter) {
		//var result = &#039;var &#039; + name;
		var result = &#039;&#039;
		if ( value ) {
			result = name;
			switch( setter.toLowerCase() ) {
			case &#039;let&#039;: result += &#039; = &quot;&#039; + value + &#039;&quot;&#039;; break;
			case &#039;set&#039;: result += &#039; = new ActiveXObject(&quot;&#039; + value + &#039;&quot;)&#039;; break;
			case &#039;get&#039;: result += &#039; = GetObject(&quot;&#039; + value + &#039;&quot;)&#039;; break;
			}
		}
		return result;
	},
	addVar: function(engine, name, value, setter) {
		var result;
		if ( this.getEngine(engine) == &quot;vbs&quot; ) {
			result = this.vbsVar(name, value, setter);
		} else {
			result = this.jsVar(name, value, setter);
		}
		this.vars.push(result);
	},

	addCode: function(engine, code, region) {
		var result = &#039;&#039;;
		if ( this.getEngine(engine) == &quot;vbs&quot; ) {
			result = &#039;USE.Execute(&quot;&#039; + code + &#039;&quot;)&#039;;
		} else {
			result = code;
		}
		this[region || &#039;main&#039;].push(result);
	},

	detectScriptFile: function(args) {
		if ( this.main.length ) {
			return;
		}
		if ( this.inLoop ) {
			return;
		}
		if ( args.length ) {
			var scriptFile = args.shift();
			var engine = /\.vbs$/.test(scriptFile) ? &#039;vbs&#039; : &#039;js&#039;;
			this.main.push(this.addScript(engine, scriptFile));
		}
	}
};
]]&gt;&lt;/script&gt;
&lt;!-- &lt;script language=&quot;javascript&quot; src=&quot;./wsx/Runner.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script language=&quot;javascript&quot;&gt;&lt;![CDATA[
//
// Code processor: Runner
// This script is the part of the wsx
//
// Copyright (c) 2019, 2020 by Ildar Shaimordanov
//

var Runner = function(Program, argv) {
	if ( Program.dryRun ) {
		Runner.dump(Program);
		return;
	}

	var modules = Program.modules.join(&#039;;\n&#039;);
	var vars = Program.vars.join(&#039;;\n&#039;);
	var begin = Program.begin.join(&#039;;\n&#039;);
	var beginfile = Program.beginfile.join(&#039;;\n&#039;);
	var main = Program.main.join(&#039;;\n&#039;);
	var endfile = Program.endfile.join(&#039;;\n&#039;);
	var end = Program.end.join(&#039;;\n&#039;);

	/*
	The following variables are declared without the keyword &quot;var&quot;. So
	they become global and available for all codes in JScript and VBScript.
	*/

	// Helper to simplify VBS importing
	USE = CreateImporter();

	// Keep a last exception
	ERROR = null;

	// Reference to CLI arguments
	ARGV = argv;

	/*
	Load provided modules
	Set user-defined variables
	*/
	eval(modules);
	eval(vars);

	if ( Program.main.length == 0 &amp;&amp; Program.inLoop == false ) {
		/*
		Run REPL
		*/
		REPL.quiet = Program.quiet;
		REPL();
		return;
	}

	if ( ! Program.inLoop ) {
		/*
		Load the main script and do nothing more.
		*/
		eval(main);
		return;
	}

	// The currently open stream
	STREAM = null;

	// The current filename, file format and file number
	FILE = &#039;&#039;;
	FILEFMT = 0;

	// The current line read from the stream
	LINE = &#039;&#039;;

	// The line number in the current file
	FLN = 0;

	// The total line number
	LN = 0;

	// Emulate the &quot;continue&quot; operator
	next = function() {
		throw new EvalError(&#039;next&#039;);
	};

	// Emulate the &quot;break&quot; operator
	last = function() {
		throw new EvalError(&#039;last&#039;);
	};

	/*
	Execute the code before starting to process any file.
	This is good place to initialize.
	*/
	eval(begin);

	if ( ! ARGV.length ) {
		ARGV.push(&#039;con&#039;);
	}

	while ( ARGV.length ) {
		FILE = ARGV.shift();

		var m = FILE.match(/^\/f:(ascii|unicode|default)$/i);

		if ( m ) {
			var fileFormats = { ascii: 0, unicode: -1, &#039;default&#039;: -2 };
			FILEFMT = fileFormats[ m[1] ];
			continue;
		}

		FLN = 0;

		/*
		Execute the code before starting to process the file.
		We can do here something while the file is not opened.
		*/
		eval(beginfile);

		try {
			STREAM = FILE.toLowerCase() == &#039;con&#039;
				? STDIN
				: FSO.OpenTextFile(FILE, 1, false, FILEFMT);
		} catch (ERROR) {
			WScript.Echo(ERROR.message + &#039;: &#039; + FILE);
			continue;
		}

		/*
		Prevent failure of reading out of STDIN stream
		The real exception number is 800a005b (-2146828197)
		&quot;Object variable or With block variable not set&quot;
		*/
		//// NEED MORE INVESTIGATION
		//try {
		//	stream.AtEndOfStream;
		//} catch (ERROR) {
		//	WScript.StdErr.WriteLine(&#039;Out of stream: &#039; + file);
		//	continue;
		//}

		while ( ! STREAM.AtEndOfStream ) {
			FLN++;
			LN++;

			LINE = STREAM.ReadLine();

			/*
			Execute the main code per each input line.
			*/
			try {
				eval(main);
			} catch (ERROR) {
				if ( ERROR instanceof EvalError &amp;&amp; ERROR.message == &#039;next&#039; ) {
					continue;
				}
				if ( ERROR instanceof EvalError &amp;&amp; ERROR.message == &#039;last&#039; ) {
					break;
				}
				throw ERROR;
			}

			if ( Program.inLoop == 2 ) {
				WScript.Echo(LINE);
			}
		}

		if ( STREAM != STDIN ) {
			STREAM.Close();
		}

		/*
		Execute the code when the file is already closed. We can do
		some finalization (i.e.: print the number of lines in the file).
		*/
		eval(endfile);
	}

	/*
	Execute the code when everything is completed.
	We can finalize the processing (i.e.: print the total number of lines).
	*/
	eval(end);
};

Runner.dump = function(Program) {
	var s = [];

	function dumpCode(code) {
		if ( code.length ) {
			s.push(code.join(&#039;;\n&#039;));
		}
	}

	dumpCode(Program.modules);
	dumpCode(Program.vars);

	if ( Program.inLoop ) {
		dumpCode(Program.begin);
		s.push(&#039;::foreach FILE do&#039;);
		dumpCode(Program.beginfile);
		s.push(&#039;::while read LINE do&#039;);
	}

	if ( Program.main.length == 0 &amp;&amp; Program.inLoop == false ) {
		s = s.concat([
			&#039;::while read&#039;,
			&#039;::eval&#039;,
			&#039;::print&#039;,
			&#039;::loop while&#039;
		]);
	}

	dumpCode(Program.main);

	if ( Program.inLoop == 2 ) {
		s.push(&#039;::print LINE&#039;);
	}

	if ( Program.inLoop ) {
		s.push(&#039;::loop while&#039;);
		dumpCode(Program.endfile);
		s.push(&#039;::loop foreach&#039;);
		dumpCode(Program.end);
	}

	WScript.Echo(s.join(&#039;\n&#039;));
};
]]&gt;&lt;/script&gt;
&lt;!-- &lt;script language=&quot;javascript&quot; src=&quot;./wsx/REPL.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script language=&quot;javascript&quot;&gt;&lt;![CDATA[
//
// Code processor: REPL
// This script is the part of the wsx
//
// Copyright (c) 2019, 2020 by Ildar Shaimordanov
//

var REPL = function() {
	if ( ! WScript.FullName.match(/cscript.exe$/i) ) {
		WScript.Echo(&#039;REPL works with cscript only&#039;);
		WScript.Quit();
	}

	while ( true ) {

		try {

			(function(storage, result) {
				/*
				A user can modify the codes of these methods so
				to prevent the script malfunctioning we have
				to keep their original codes and restore them later
				*/
				eval = storage.eval;
				REPL = storage.REPL;

				if ( result === void 0 ) {
					return;
				}

				if ( result &amp;&amp; typeof result == &#039;object&#039;
				&amp;&amp; console &amp;&amp; typeof console == &#039;object&#039;
				&amp;&amp; typeof console.log == &#039;function&#039; ) {
					console.log(result);
				} else {
					WScript.StdOut.WriteLine(&#039;&#039; + result);
				}
			})({
				eval: eval,
				REPL: REPL
			},
			eval((function(PS1, PS2) {

				if ( REPL.quiet ) {
					PS1 = &#039;&#039;;
					PS2 = &#039;&#039;;
				} else {
					var me = WScript.ScriptName;
					PS1 = me + &#039; js &gt; &#039;;
					PS2 = me + &#039; js :: &#039;;
				}

				/*
				The REPL.history can be changed by the user as he
				can. We should prevent a concatenation with the one
				of the empty values such as undefined, null, etc.
				*/
				if ( ! REPL.history || ! ( REPL.history instanceof [].constructor ) ) {
					REPL.history = [];
				}

				/*
				The REPL.number can be changed by the user as he can.
				We should prevent an incrementing of non-numeric values.
				*/
				if ( ! REPL.number || typeof REPL.number != &#039;number&#039; ) {
					REPL.number = 0;
				}

				/*
				The line consisting of two colons only switches the
				multiline mode. The first entry of double colons
				means turn on the multiline mode. The next entry
				turns off. In the multiline mode it&#039;s possible to
				type a code of few lines without inpterpreting.
				*/
				var multiline = false;

				/*
				Storages for:
				-- one input line
				-- one or more input lines as array
				   (more than one are entered in multiline mode)
				-- the resulting string of all entered lines
				   (leading and trailing whitespaces are trimmed)
				*/
				var input = [];
				var inputs = [];
				var result = &#039;&#039;;

				WScript.StdOut.Write(PS1);

				while ( true ) {

					try {
						REPL.number++;
						input = [];
						while ( ! WScript.StdIn.AtEndOfLine ) {
							input[input.length] = WScript.StdIn.Read(1);
						}
						WScript.StdIn.ReadLine();
					} catch (ERROR) {
						input = [ &#039;WScript.Quit()&#039; ];
					}

					if ( input.length == 2 &amp;&amp; input[0] + input[1] == &#039;::&#039; ) {
						input = [];
						multiline = ! multiline;
					}

					if ( inputs.length ) {
						inputs[inputs.length] = &#039;\n&#039;;
					}
					for (var i = 0; i &lt; input.length; i++) {
						inputs[inputs.length] = input[i];
					}

					if ( ! multiline ) {
						break;
					}

					WScript.StdOut.Write(PS2);

				} // while ( true )

				// Trim left
				var k = 0;
				while ( inputs[k] &lt;= &#039; &#039; ) {
					k++;
				}
				// Trim right
				var m = inputs.length - 1;
				while ( inputs[m] &lt;= &#039; &#039; ) {
					m--;
				}

				var result = &#039;&#039;;
				for (var i = k; i &lt;= m; i++) {
					result += inputs[i];
				}

				if ( result == &#039;&#039; ) {
					return &#039;&#039;;
				}

				REPL.history[REPL.history.length] = result;

				return result;

			})()));

		} catch (ERROR) {

			WScript.StdErr.WriteLine(WScript.ScriptName
				+ &#039;: &quot;&lt;stdin&gt;&quot;, line &#039; + REPL.number
				+ &#039;: &#039; + ERROR.name
				+ &#039;: &#039; + ERROR.message);

		}

	} // while ( true )
};
]]&gt;&lt;/script&gt;
&lt;!-- &lt;script language=&quot;javascript&quot; src=&quot;./wsx/CommandLine.js&quot;&gt;&lt;/script&gt; --&gt;
&lt;script language=&quot;javascript&quot;&gt;&lt;![CDATA[
//
// Command Line processor
// This script is the part of the wsx
//
// Copyright (c) 2019, 2020 by Ildar Shaimordanov
//

(function(Program, Runner, REPL) {

	var argv = [];

	function ShowVersion() {
		var me = WScript.ScriptName.replace(/(\.[^.]+\?)?\.[^.]+$/, &#039;&#039;);
		var name = typeof NAME == &#039;string&#039; ? NAME : me;
		var version = typeof VERSION == &#039;string&#039; ? VERSION : &#039;0.0.1&#039;;
		WScript.Echo(name + &#039; (&#039; + me + &#039;): Version &#039; + version
			+ &#039;\n&#039; + WScript.Name
			+ &#039;: Version &#039; + WScript.Version
			+ &#039;, Build &#039; + WScript.BuildVersion);
	}

	// Walk through all named and unnamed arguments because
	// we have to handle each of them even if they duplicate
	for (var i = 0; i &lt; WScript.Arguments.length; i++) {

		var arg = WScript.Arguments.Item(i);

		var m;

		m = arg.match(/^\/h(?:elp)?$/i);
		if ( m ) {
			WScript.Arguments.ShowUsage();
			WScript.Quit();
		}

		m = arg.match(/^\/version$/i);
		if ( m ) {
			ShowVersion();
			WScript.Quit();
		}

		m = arg.match(/^\/dry-run$/i);
		if ( m ) {
			Program.dryRun = true;
			continue;
		}

		m = arg.match(/^\/q(?:uiet)?$/i);
		if ( m ) {
			Program.setQuiet();
			continue;
		}

		m = arg.match(/^\/use:(js|vbs)$/i);
		if ( m ) {
			Program.setEngine(m[1]);
			continue;
		}

		m = arg.match(/^\/m(?::(js|vbs))?:(.+)$/i);
		if ( m ) {
			Program.addModule(m[1], m[2]);
			continue;
		}

		m = arg.match(/^\/(let|set|get)(?::(js|vbs))?:(\w+)=(.*)$/i);
		if ( m ) {
			Program.addVar(m[2], m[3], m[4], m[1]);
			continue;
		}

		m = arg.match(/^\/(?:e|((?:begin|end)(?:file)?))(?::(js|vbs))?(?::(.*))?$/i);
		if ( m ) {
			Program.addCode(m[2], m[3], m[1]);
			continue;
		}

		m = arg.match(/^\/([np])$/i);
		if ( m ) {
			Program.setMode(m[1]);
			continue;
		}

		/*
		This looks like ugly, but it works and reliable enough to
		stop looping over the rest of the CLI options. From this
		point we allow end users to specify their own options even,
		if their names intersect with names of our options.
		*/
		break;

	}

	for ( ; i &lt; WScript.Arguments.length; i++) {
		var arg = WScript.Arguments.Item(i);
		argv.push(arg);
	}

	Program.detectScriptFile(argv);

	Runner(Program, argv);

})(Program, Runner, REPL);
]]&gt;&lt;/script&gt;

&lt;/job&gt;
&lt;/package&gt;
</code></pre></div></div></div>]]></content>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2020-02-28T23:19:12Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=138152#p138152</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=102632#p102632" />
			<content type="html"><![CDATA[<p>Очень интересная тема! Будем разбираться!<br />Спасибо вам за труды!</p>]]></content>
			<author>
				<name><![CDATA[NovaRo]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=33786</uri>
			</author>
			<updated>2016-04-16T14:50:48Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=102632#p102632</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=77487#p77487" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>для получения времени используется WMIC.EXE, под ограниченной учётной записью это не работает</p></blockquote></div><p>Речь идет об этой команде:<br /></p><div class="codebox"><pre><code>
WMIC path win32_localtime get Hour,Minute,Second /value
</code></pre></div><p>Полагаю, что другие средства не имеют таких ограничений, например:<br /></p><div class="codebox"><pre><code>
powershell -command &quot;date -uformat &#039;%H%M%S&#039;&quot;
</code></pre></div><p>У меня вопрос к знатокам и пользователям с ограниченной учеткой. Как работает следующая команда именно под ограниченной учеткой. Доступна ли она и ее результат для непривилегированного пользователя?</p><div class="codebox"><pre><code>
powershell -command &quot;(gwmi win32_process -filter processid=$pid).parentprocessid&quot;
</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2013-11-23T16:47:39Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=77487#p77487</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=75751#p75751" />
			<content type="html"><![CDATA[<p>Не один я маюсь. (-:</p><p>JavaScript REPL for Windows в трех частях<br /><a href="http://sinesquare.wordpress.com/2011/08/25/javascript-repl-for-windows-part1motivation-choices-and-first-steps/">часть 1</a><br /><a href="http://sinesquare.wordpress.com/2011/08/25/javascript-repl-for-windows-part-2breakpoints-and-debug-repl/">часть 2</a><br /><a href="http://sinesquare.wordpress.com/2011/08/25/javascript-repl-for-windows-part-3dynamic-breakpoints/">часть 3</a></p>]]></content>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2013-10-04T16:04:36Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=75751#p75751</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=73139#p73139" />
			<content type="html"><![CDATA[<p>Вернулся к своему интерпретатору. Сделал небольшое, но существенное исправление: <br /></p><div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p><strong>$$$wscmd_.wsf</strong> лучше удалять сразу после его запуска</p></blockquote></div><p>По-прежнему можно скачать <a href="https://github.com/ildar-shaimordanov/jsxt/archive/master.zip">архив скрипта</a>, поиграться со скриптом и сообщить о своих впечатлениях. Свежая версия программы всегда доступны из <a href="https://github.com/ildar-shaimordanov/jsxt/blob/master/wscmd.bat		">репозитория</a>.</p>]]></content>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2013-06-20T07:12:38Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=73139#p73139</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=66238#p66238" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>Может вместо мучений с поиском уникальных значений пойти другим путём?</p></blockquote></div><p>Даже при практически приемлемых способах получения уникальных значений, остаётся теоретическая вероятность их совпадений. Поэтому при одновременном запуске нескольких экземпляров программы полагаться лишь на предварительную проверку незанятости имени файла не стоит — нужно ещё <a href="http://script-coding.com/forum/viewtopic.php?pid=66053#p66053">обрабатывать</a> попытки одновременного доступа к нему. А в этом случае можно не заботится об уникальности начального значения. При этом, если в качестве начального значения можно брать как всегда одно и тоже, так и псевдослучайное, то перебирать значения при неудаче лучше последовательно, не обращаясь более к генератору псевдослучайных чисел (как это имеет место в теме «<a href="http://script-coding.com/forum/viewtopic.php?id=6259">CMD/BAT: генерация пути для временного файла или папки</a>»), т.к. особенности исполнения генератора псевдослучайных чисел могут допускать возможность его зацикливания.</p><p>В приведённом примере попытка записи во временный файл *.js приведёт к ошибке, если он открыт на запись другим процессом или имеет атрибут «Только чтение», причём атрибут нужно устанавливать не закрывая файл, иначе файл может быть перехвачен (используется атрибут, т.к. просто запустить сценарий WSH, пока он ещё открыт на запись не получится), которая (ошибка) обрабатывается изменением (увеличением на 1) переменной части имени временного файла и повтором попытки.</p><p>Временный файл скрипта удаляется после запуска из самого себя потому, что при таком подходе временные файлы желательно удалять сразу после их использования (в данном случае использование — запуск скрипта из файла на исполнение), чтобы не занимать потенциальные имена.</p>]]></content>
			<author>
				<name><![CDATA[wisgest]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=3850</uri>
			</author>
			<updated>2012-11-28T10:03:55Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=66238#p66238</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=66231#p66231" />
			<content type="html"><![CDATA[<p>Может вместо мучений с поиском уникальных значений пойти другим путём?</p><p><strong>test.bat</strong>:<br /></p><div class="codebox"><pre><code>@echo off
setlocal enableextensions
set x=0
:REPEAT
((
  echo,var fso = new ActiveXObject(&quot;Scripting.FileSystemObject&quot;^);
  echo,try {fso.DeleteFile(WScript.ScriptFullName, true^);} catch (Err^) {}
  echo,WScript.Echo(WScript.ScriptFullName^);
  echo,WScript.StdErr.WriteLine(&quot;[%~1]&quot;^);
  attrib +r &quot;%~f0.%x%.js&quot;&gt;nul
)&gt;&quot;%~f0.%x%.js&quot;) 2&gt;nul || (set /a &quot;x+=1&quot; &amp; goto REPEAT)
CScript.exe //logo &quot;%~f0.%x%.js&quot;
endlocal</code></pre></div><p>Испытания:<br /></p><div class="codebox"><pre><code>for /l %i in (1 1 20) do @start &quot;%i&quot; cmd /c test.bat %i ^&amp; pause
test 1 | test 2
test 1 1&gt;&amp;2 | test 2</code></pre></div><p>(В последних случаях выводимые строки смешиваются в произвольном порядке: чаще «[1]» предшествует «[2]», иногда наоборот…)</p>]]></content>
			<author>
				<name><![CDATA[wisgest]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=3850</uri>
			</author>
			<updated>2012-11-28T00:24:55Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=66231#p66231</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=66226#p66226" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>Проблема понятна, но это относится к подстановке $UID, а не $TIME —<br />чем время полученное через WMIC лучше %TIME%?<br />А если на запуск WMIC не хватит прав $TIME заменится пустой подстрокой.</p></blockquote></div><p>Ни чем кроме региональных отличий в представлении времени. Я просто не уверен, что время везде представлено в формате ЧЧ:ММ:СС. <br />Другой момент. Если брать время из переменной %TIME%, то в случае запуска программы в конвейере это значение будет для всех процессов одно. Опять коллизия, от которой я пытался уйти. </p><div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>Неужели я так путанно объясняю?</p></blockquote></div><p>Я подумал, что Вы запустили конвейер., а программа пыталась подобрать уникальный UID. Симптомы похожие.</p>]]></content>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2012-11-27T19:20:27Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=66226#p66226</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=66225#p66225" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>Rumata пишет:</cite><blockquote><div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>Почему вместо WMIC.EXE не использовать псевдопеременную %TIME%</p></blockquote></div><p>Эта проблема связана с тем, что при запуске WSCMD в конвейера вида wscmd | wscmd возникают коллизии, которые я когда-то описал в теме <a href="http://script-coding.com/forum/viewtopic.php?id=6256">Проблема создания уникальных значений в конвейерных командах</a>.</p></blockquote></div><p>Проблема понятна, но это относится к подстановке $UID, а не $TIME —<br />чем время полученное через WMIC лучше %TIME%?<br />А если на запуск WMIC не хватит прав $TIME заменится пустой подстрокой.</p><div class="quotebox"><cite>Rumata пишет:</cite><blockquote><div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>омандный файл зависал, безуспешно пытаясь подобрать новое</p></blockquote></div><p>&lt;…&gt; Видимо у Вас удалось наблюдать коллизию, которую я предсказывал там же…</p></blockquote></div><p>Неужели я так путанно объясняю? Вот полный код процедуры:<br /></p><div class="codebox"><pre><code>:wscmd.execute.uid
    for /f &quot;tokens=1,2 delims==; &quot; %%a in ( 
        &#039;%WMIC% Process call create &quot;%windir%\System32\wscript.exe //b&quot; 2^&gt;nul ^| %FIND% &quot;ProcessId&quot;&#039; 
    ) do (
        set wscmd.uid=%%b
    )

    set wscmd.tmpfile=!wscmd.execute:$UID=%wscmd.uid%!
if exist &quot;!wscmd.tmpfile!&quot; goto wscmd.execute.uid

set wscmd.execute=%wscmd.tmpfile%
goto :EOF</code></pre></div><p>Причина «коллизии» в ошибке, сообщение о которой подавляется:<br /></p><div class="quotebox"><blockquote><p>Ошибка при регистрации mof-файлов.<br />Использовать WMIC.EXE могут только администраторы.<br />Причина:Ошибка Win32: Отказано в доступе.</p></blockquote></div><p>В этом случае опять же вместо $UID подставляется пустое значение, при первом запуске это не страшно, но если файл уже существует, то выхода из цикла не будет.<br />Вероятно, надо не только подавлять сообщение об ошибке, но и как-то его обрабатывать, например, за неимением пока лучшего, предложить ввести значение вручную.</p>]]></content>
			<author>
				<name><![CDATA[wisgest]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=3850</uri>
			</author>
			<updated>2012-11-27T18:04:04Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=66225#p66225</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=66197#p66197" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>для получения времени используется WMIC.EXE, под ограниченной учётной записью это не работает</p></blockquote></div><p>это заставляет меня обоснованно ненавидеть рэдмондских волшебников.</p><div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>Почему вместо WMIC.EXE не использовать псевдопеременную %TIME%</p></blockquote></div><p>Эта проблема связана с тем, что при запуске WSCMD в конвейера вида wscmd | wscmd возникают коллизии, которые я когда-то описал в теме <a href="http://script-coding.com/forum/viewtopic.php?id=6256">Проблема создания уникальных значений в конвейерных командах</a>. </p><div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>омандный файл зависал, безуспешно пытаясь подобрать новое</p></blockquote></div><p>Там же <a href="http://script-coding.com/forum/viewtopic.php?pid=59038#p59038">№42</a> есть временное обходное решение. Видимо у Вас удалось наблюдать коллизию, которую я предсказывал там же:<br /></p><div class="quotebox"><cite>Rumata пишет:</cite><blockquote><p>WSCRIPT //B - пока единственная более-менее надежная команда, которую можно запустить и которая пока ни разу не привела к коллизиям. Хотя коллизии теоретически возможны и с нею.</p></blockquote></div>]]></content>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2012-11-26T20:45:54Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=66197#p66197</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=66191#p66191" />
			<content type="html"><![CDATA[<p>P.S. </p><div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>Почему вместо WMIC.EXE не использовать псевдопеременную %TIME%</p></blockquote></div><p>В общем-то можно и в самом файле настроек указать не <strong>$TIME</strong>, а <strong>%TIME::=%</strong>…</p>]]></content>
			<author>
				<name><![CDATA[wisgest]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=3850</uri>
			</author>
			<updated>2012-11-26T19:17:22Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=66191#p66191</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=66190#p66190" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>wscmd /man пишет:</cite><blockquote><p>execute<br />&nbsp; &nbsp; This option defines a name of the resulting file. If it is not specially <br />&nbsp; &nbsp; specified, the default value will be used. There are two placeholders <br />&nbsp; &nbsp; $TIME, the current time, and $UID, the unique number generated by <br />&nbsp; &nbsp; the program, to make the resulting filename unique.</p></blockquote></div><p>Попробовал указать <strong>$TIME</strong>: поскольку для получения времени используется WMIC.EXE, под ограниченной учётной записью это не работает — вместо $TIME ничего в имя WSF не подставляется (он создаётся и успешно запускается).</p><p>Почему вместо WMIC.EXE не использовать псевдопеременную %TIME% (насколько я могу судить, её формат не зависит от региональных настроек, в отличии от %DATE%, да это и не важно)?</p><p>(<span class="bbu">28.11.2012</span>: Всё-таки зависит (от разделителя компонентов времени <em>sTime</em> и разделителя целой и дробной части <em>sDecimal</em>, но не от общего формата времени <em>sTimeFormat</em>), но изменения, даже если они сделаны через Панель управления, на уже запущенный процесс CMD.EXE не влияют, в отличии от <em>%DATE%</em>, которая мгновенно реагирует на изменения параметра <em>sShortDate</em>.)</p><p>Исчезла описанная ранее ошибка:<br /></p><div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>если не завершая работы закрыть окно консоли или запустить новый экземпляр, то он зависает, нагружая процессор.</p></blockquote></div><p>— при указании <strong>$UID</strong> у меня вместо него тоже ничего не подставлялось, но если файл с таким именем уже существовал, командный файл зависал, безуспешно пытаясь подобрать новое:<br /></p><div class="codebox"><pre><code>if exist &quot;!wscmd.tmpfile!&quot; goto wscmd.execute.uid</code></pre></div><p>— ага, здесь опять WMIC.EXE и сообщения об ошибках подавляются. Почему в качестве <strong>$UID</strong> просто не взять целое число (0), наращивая на 1, если файл существует?</p><br /><p>Сказанное, не отменяет необходимость, чтобы не собирался мусор, удалять временный WSF, не дожидаясь, пока пользователь введёт «quit()» — более вероятно, что он просто закроет окно. Удалять файл скрипта из него самого вполне безопасно, т.к. он уже запустился.</p>]]></content>
			<author>
				<name><![CDATA[wisgest]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=3850</uri>
			</author>
			<updated>2012-11-26T19:03:54Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=66190#p66190</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=66087#p66087" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>не нравится как задаются «относительные» пути в этом месте и в файле настроек и, кажется, их несложно переделать на настоящие относительные пути</p></blockquote></div><p>Три варианта. Использовать стандартные разделители путей: пробел или точку с запятой. Придумать свой разделитель, чтобы исключить попадание пробела или точки с запятой в имя пути или файла. Например, &quot;файл; файл же.js&quot;. Третий вариант - кавычки. Он и используется. </p><p>А приведенная Вами строка - мой косяк. Исправьте ее на следующую. Позже исправлю в репозитории. <br /></p><div class="codebox"><pre><code>if not defined wscmd.ini.include set wscmd.ini.include=&quot;%~dp0js\*.js&quot; &quot;%~dp0js\win32\*.js&quot; &quot;%~dp0vbs\win32\*.vbs&quot;</code></pre></div><div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>Не знаю, может ли это оказаться чем-то полезно: Convert Unicode to ASCII vv?<br />Вроде бы (не вникал), что-то похожее есть в теме smaharbA «CMD/BAT: О кодировке»<br />в процедуре :iconv (from,to,input).</p></blockquote></div><p>Спасибо. Посмотрю. Главное, чтобы это еще больше не усложнило. </p><p>START /B работает как-то странно. У меня в одних случаях происходит &quot;наложение&quot; на командную строку, в других - выводит ошибку. Но это опять упирается все в проблему кодировок Unicode, cp866, windows-1251 и прочие, в зависимости от локали.</p>]]></content>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2012-11-24T08:03:25Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=66087#p66087</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=66086#p66086" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>Rumata пишет:</cite><blockquote><div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>применяются какие-то стандартные значения</p></blockquote></div><p>Я полностью согласен, что было бы неплохо использовать стандартные значения. Или найти простой способ использовать Unicode как стандартное значение для XML.</p></blockquote></div><p>Э-э… я имел в виду (если правильно нашёл место):<br /></p><div class="codebox"><pre><code>:: Set defaults
...
...
if not defined wscmd.ini.include set wscmd.ini.include=%~dp0js\*.js %~dp0js\win32\*.js %~dp0vbs\win32\*.vbs</code></pre></div><p>— возможно (не проверял), здесь не хватает каких-то кавычек. И в целом мне не нравится как задаются «относительные» пути в этом месте и в файле настроек и, кажется, их несложно переделать на настоящие относительные пути. Может попозже подумаю над этим…</p><div class="quotebox"><cite>Rumata пишет:</cite><blockquote><p>…И команда <strong>chcp</strong> в этом случае плохой. И других способов разрешить эту проблему нет.</p></blockquote></div><p>Не знаю, может ли это оказаться чем-то полезно: <a href="http://www.robvanderwoude.com/type.php#Unicode">Convert Unicode to ASCII <strong>vv</strong></a>?<br />Вроде бы (не вникал), что-то похожее есть в теме <strong>smaharbA</strong> «<a href="http://forum.script-coding.com/viewtopic.php?id=7683">CMD/BAT: О кодировке</a>»<br />в процедуре <em>:iconv (from,to,input)</em>.</p><div class="quotebox"><cite>Rumata пишет:</cite><blockquote><p>Главное чтобы не возникло ситуации, когда WSH еще загружает файл, а мы уже пытаемся удалить его.</p></blockquote></div><p>Не уверен насчёт START, но если удалять WSF-скрипт из самого себя, то если он начал выполнятся, то уже должен быть полностью загружен.</p>]]></content>
			<author>
				<name><![CDATA[wisgest]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=3850</uri>
			</author>
			<updated>2012-11-24T07:02:51Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=66086#p66086</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: JScript/VBScript: WSH интерпретатор]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=66079#p66079" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>применяются какие-то стандартные значения</p></blockquote></div><p>Я полностью согласен, что было бы неплохо использовать стандартные значения. Или найти простой способ использовать Unicode как стандартное значение для XML. Но как быть с файлами (не именами а именно содержимым файлов), которые могут содержать символы в другой кодировке. Вот пример. По умолчанию, консоль использует cp866, WSF-файл - Unicode, а подключается с помощью /embed файл, содержащий символы windows-1251. И команда <strong>chcp</strong> в этом случае плохой. И других способов разрешить эту проблему нет. </p><p>Хотя можно использовать короткие имена. Так можно решить проблему не-ASCII символов в именах файлов. Но не решит всех проблем. </p><div class="quotebox"><cite>wisgest пишет:</cite><blockquote><p>Можно попробовать запускать его через START /B</p></blockquote></div><p>Возможно. Главное чтобы не возникло ситуации, когда WSH еще загружает файл, а мы уже пытаемся удалить его. Кстати, опция START /I очень симпатична в этом случае, чтобы не загрязнять окружение WSF-скрипта собственными вспомогательными переменными. И главное, чтобы скрипты запускались вообще в принципе. </p><p>Я понимаю, что всё это выглядит как нечто с заявками на некую универсальность, но теми средствами, что я использую для их реализации, добиться весьма сложно. Естественно, я тестировал скрипт в окружении вида <strong>C:\Это моя\песочница</strong>, но в то время я был доволен своими тестами. К сожалению подробностей вспомнить уже не могу. </p><div class="quotebox"><cite>smaharbA пишет:</cite><blockquote><p>не читал, но осуждаю</p></blockquote></div><p>Как же можно так? Взрослый, серьезный человек, а закусили без выпивки. Извините за витиеватый слог, Вам подражаю. А mshta как средство для полноценного запуска скриптов и библиотеки скриптов еще тот костыль.</p>]]></content>
			<author>
				<name><![CDATA[Rumata]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24846</uri>
			</author>
			<updated>2012-11-23T19:52:41Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=66079#p66079</id>
		</entry>
</feed>
