1 (изменено: badik, 2014-03-06 11:03:22)

Тема: JScript: гибрид WSH и NET

Любой скрипт не использующий в  префиксные функции CreateObject ( второй параметр :Префикс функций-обработчиков событий) можно скомпилироать в NET


1. Используем условную компиляцию
2. Переменные должны быть объявленны (типизировать НЕ обязательно)
3. Заменям значения и методы объекта WScript на свои
4. CreateObject на ActiveXObject
5. в eval добовляем второй параметр 'unsafe'
6. Компилируем

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\jsc.exe /t:exe /platform:x86 /debug-  %1

7. Управление выводом ошибок в NET

Пример скрипта работающего в двух средах
1. функция LIB.time получена с помощью  eval(...,'unsafe')
2. бонусы в NET:
2.1 Прерывание паузы при нажатии любой клавиши (свойство KeyAvailable ) - аналог timeout.exe
2.2 Усиленная очитка памяти


+ Пример гибрида
@if( @_jscript_version >= 7 )
@set @js_dotnet = 1
@else
@set @js_dotnet = 0
@end

@if( @js_dotnet )
import System;
import System.Threading;
import System.IO;
@end


function _quit( exitcode )
{
    @if( @js_dotnet )
    Environment.Exit( exitcode );
    @else
    WScript.Quit( exitcode );
    @end
}


function _sleep( x )
{
    @if( @js_dotnet )
    Thread.Sleep( new TimeSpan(0,0,0,0,x));
    @else
    WScript.Sleep( x );
    @end
}


function _print( txt )
{
    @if( @js_dotnet )
    print( txt );
    @else
    WScript.Echo( txt );
    @end
}

function _ScriptFullName( )
{
    @if( @js_dotnet )
    return( Environment.GetCommandLineArgs()[0] );
    @else
    return( WScript.ScriptFullName );
    @end
}



function _arg()
{
// Автор функции Rumanta

    @if( @js_dotnet )
        var cmdLine= Environment.CommandLine;
    @else

    var cmdLine = WScript.ScriptFullName
    for (var ff = new Enumerator(WScript.Arguments); !ff.atEnd(); ff.moveNext())
    cmdLine += ' ' + ff.item().replace(/(^.+ .+$)/, '"$1"')

    @end


    var re = new RegExp([
        // named arguments rounded or not by the quote characters
        //     /named
        // where the 'named' term stands for one of the following:
        //     /key+        key is true
        //     /key-        key is false
        //     /key
        //     /key:
        //     /key:""        key is an empty string
        //     /key:value
        //     /key:"value"    key contains the string 'value'
        '(', 
            '\\/', 
            '([\\S]+?)', 
            '(?:', 
                // /key+
                '(\\+)', 
 
                '|', 
 
                // /key-
                '(\\-)', 
 
                '|', 
 
                // /key:"value"
                // /key:""
                ':"(.*?)"', 
 
                '|', 
 
                // /key:value
                // /key:
                ':([\\S]*)', 
            ')?', 
 
            '|', 
 
            // unnamed arguments rounded by the quote characters
            //     "value"
            '"(.*?)"', 
 
            '|', 
 
            // unnamed arguments without the quote characters
            //     value
            '([\\S]+)', 
        ')', 
        '(?:\\s+|$)', 
    ].join(''), 'g');
 
    var r;
 
    // It's impossible but we are paranoic
    r = re.exec(cmdLine);
    if ( ! r ) {
        return;
    }
 
    var fullname = (r[7] || r[8]).replace(/"/g, '');
    var filename = fullname.replace(/^.+\\/, '');
    var pathname = fullname.replace(/\\[^\\]+$/, '');
 
    var args = [];
 
    var unnamed = [];
 
    var named = {};
    var named_length = 0;
    var named_keys = [];
 
    while ( r = re.exec(cmdLine) ) {
        var k = r[2];
        var v = r[3] ? true : r[4] ? false : r[5] || r[6] || r[7] || r[8];
 
        if ( ! k && ! v ) {
            continue;
        }
 
        args.push(k?r[1]:v);
 
        if ( ! k ) {
            unnamed.push(v);
            continue;
        }
 
        named_length++;
        named[k] = (named[k] || []).concat(v);
        (function()
        {
            for (var i = 0; i < named_keys.length; i++) {
                if ( k == named_keys[i] ) {
                    return;
                }
            }
            named_keys.push(k);
        })();
    }
 
return {
        arguments: {
            named: {
                exists: function(key)
                {
                    return named.hasOwnProperty(key);
                }, 
                item: function(key)
                {
                    return named[key];
                }, 
                keys: function()
                {
                    return [].concat(named_keys);
                }, 
                length: function()
                {
                    return named_keys.length;
                }
            }, 
            unnamed: {
                item: function(index)
                {
                    return unnamed[index];
                }, 
                length: function()
                {
                    return unnamed.length;
                }
            }, 
            item: function(index)
            {
                return args[index];
            }, 
            length: function()
            {
                return args.length;
            }
        }, 
        appFullName: fullname, 
        appPath: pathname, 
        appName: filename, 
        cmdLine: cmdLine
    };
 
}

var fso = new ActiveXObject("Scripting.FileSystemObject");
var shell = new ActiveXObject("WScript.Shell")
var LIB={}
eval(sText(),'unsafe')


main()

function main()
{


    @if( @js_dotnet )
    @else

if (WScript.FullName.toUpperCase().indexOf("CSCRIPT") < 0) {

    var Param = WScript.ScriptFullName.replace(/(^.+ .+$)/, '"$1"')
    for (var ff = new Enumerator(WScript.Arguments); !ff.atEnd(); ff.moveNext())
    Param += ' ' + ff.item().replace(/(^.+ .+$)/, '"$1"')

        var saveDir = shell.CurrentDirectory
    shell.Run("cscript.exe  " + Param, 1)
    shell.CurrentDirectory = saveDir
    _quit(0)

}
    @end

var wArg=_arg()
var t= new Date()


_print("пауза 10 секунд")

@if( @js_dotnet )
_print("NET:нажмите любую клавишу для ускорения")
@end

while (true)
{
_print(wArg.appName +" время работы:"+LIB.timer(t))

@if( @js_dotnet )
var waitTime:TimeSpan = TimeSpan.FromSeconds(10.0);
   var keyPressed = false
   var expireTime:DateTime = DateTime.Now + waitTime; 
   while ((!keyPressed) && (DateTime.Now < expireTime))
    {     
    if (Console.KeyAvailable)     
 {          Console.ReadKey(true);
        keyPressed = true;     }
     Thread.Sleep(10);
 } 
@else
_sleep(10000)
@end
CollectGarbage()
@if( @js_dotnet )
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
@end
}

}

function sText()
{
return "\n\
LIB.timer=function (t) {\n\
    var tt = new Date()\n\
    var d = (new Date(tt - t))\n\
    d.setMinutes(d.getMinutes() + d.getTimezoneOffset())\n\
    return (\"\" + r(d.getHours()) + \":\" + r(d.getMinutes()) + \":\" + r(d.getSeconds()))\n\
\n\
        function r(d) {\n\
            var s = \"00\" + d\n\
            return (s.substr(s.length - 2, 2))\n\
        }\n\
}\n\
"
}

2

Re: JScript: гибрид WSH и NET

Простите, но лет эдак десять тому назад о подобном писал Джастин Роджерс.

3

Re: JScript: гибрид WSH и NET

greg zakharov пишет:

Простите, но лет эдак десять тому назад о подобном писал Джастин Роджерс.

На этом форуме?

4

Re: JScript: гибрид WSH и NET

wisgest пишет:

На этом форуме?

А Вы шутник. Вообще-то речь была об одной из книг вышеупомянутого гражданина. Но похоже как-то его книги прошли не особо замеченными. И потом, если играться с различными компиляторами, в частности с jsc.exe, можно творить вещи, которые вне всякой логики. Хотелось бы привести пару примеров, но правила форума не позволяют писать код, сопряженный с малварью.

5 (изменено: badik, 2014-03-07 05:36:45)

Re: JScript: гибрид WSH и NET

greg zakharov - я это знаю. У меня есть книга Джастин Роджерс   купленная   по уценке в магазине.
К большому сожелению слова WScript, eval в книге не встречаются.
WSH на стр 13,17,194 лишь расшифровывается как....
В книге во всех примерах объявлены только типизированные переменные. Про обратную совместимость ни слова.

Объявлять типизированные переменный пришлось в одном месте 

var tBytes:Int32  = Int32(Convert.ChangeType(objDataReader.GetBytes(i, 0, null, 0, int.MaxValue), Int32));
var outbyte:byte[] = new byte[tBytes];

во всех остальных случаях у меня код для NET и WSH одинаков

  var fso = new ActiveXObject("Scripting.FileSystemObject");
  var lFile = fso.OpenTextFile("fio.dat", 1, false)
  var o = {}
  var s,a
  while(!lFile.AtEndOfStream)
  {
    s = lFile.ReadLine()
    o[s] = 1
  }
  lFile.Close()

Вопрос в другом.
Если есть  много и давно  написанных и отлаженных скриптов на JScript.WSH
Но теперь по требованию безопасности необходимо защитить код от изменений и запускать его с другими правами (логином)   утилитой типа adminlink.
Предложенный вариант (рыба) поможет быстрее справится с проблемой.

Мне нравится отлаживать скрипты в отладчике MS Office. Только готовый скрипт компилирется jsc.exe

6

Re: JScript: гибрид WSH и NET

Именно благодаря этой теме заинтересовался в какой-то степени JScript.NET.
Как я понял, наряду с новыми возможностями в духе C# JScript.NET поддерживает и старые: бестиповые (точнее Variant) переменные, прототипное наследование…
Заинтересовавшись, наткнулся на книгу «вышеупомянутого гражданина» и скачал себе, правда, нашёл только на английском, а на русском электронную версию можно заказать на сайте «Диалектика».

7 (изменено: wisgest, 2014-03-06 19:05:04)

Re: JScript: гибрид WSH и NET

wisgest пишет:

Как я понял, наряду с новыми возможностями в духе C# JScript.NET поддерживает и старые: бестиповые (точнее Variant) переменные, прототипное наследование…

Насчёт прототипного наследования я, похоже, ошибся (добавлено: не совсем — см. дальше)
хотя функции в качестве конструкторов объектов поддерживаются.

8

Re: JScript: гибрид WSH и NET

Уважаемый badik, если бы Вы были предельно внимательны, то увидели бы что я написал ранее. Ко всему прочему в древних спецификациях MS также упомяналось, что WSH запросто можно компилировать jsc.exe, так что снова мимо.

badik пишет:

Но теперь по требованию безопасности необходимо защитить код от изменений и запускать его с другими правами (логином)   утилитой типа adminlink.

И Вы свято верите, что скомпилированный код защищен от изменений?

badik пишет:

Мне нравится отлаживать скрипты в отладчике MS Office.

Это скорее уже парад пристрастий. Я же никому не навязываю использовать Vim или редактор Far'а.

wisgest пишет:

Именно благодаря этой теме заинтересовался в какой-то степени JScript.NET.

Сходу:

import Accessibility;
import System;
import System.Drawing;
import System.Reflection;
import System.Windows.Forms;
import System.Runtime.InteropServices;

import ClipboardImage;

[assembly: AssemblyVersion("2.0.0.0")]
[assembly: ComVisible(false)]
[assembly: CLSCompliant(true)]

package ClipboardImage {
  class frmMain extends Form {
    public function frmMain() {
      InitializeComponent();
    }

    private var pbClip : PictureBox;
    private var sbSizer : StatusBar;

    private function InitializeComponent() {
      this.pbClip = new PictureBox;
      this.sbSizer = new StatusBar;
      //
      //pbClip
      //
      this.pbClip.Dock = DockStyle.Fill;
      //
      //sbSizer
      //
      this.sbSizer.Dock = DockStyle.Bottom;
      this.sbSizer.SizingGrip = false;
      //
      //frmMain
      //
      this.ClientSize = new System.Drawing.Size(450, 450);
      this.Controls.AddRange(Control[] ([this.pbClip, this.sbSizer]))
      this.StartPosition = FormStartPosition.CenterScreen;
      this.Text = "Clipboard Image";
      this.add_Load(frmMain_Load);
    }

    private function frmMain_Load(sender : Object, e : EventArgs) : void {
      if (Clipboard.ContainsImage()) {
        var img : Image = Clipboard.GetImage();
        pbClip.Image = img;
        sbSizer.Text = img.Width + " x " + img.Height;
      }
    }
  }

  class Program {
    STAThreadAttribute() static function Main() : void {
      Application.EnableVisualStyles();
      Application.Run(new frmMain());
    }
  }
}

Program.Main();

Правда я не учитывал вопросы безопасности.
На счет WSH повторюсь - известно давно. Странно, что только сейчас о JScript.NET задискутировали.

9

Re: JScript: гибрид WSH и NET

greg zakharov, это не страшно. Я, например, пока мне явно не указали, не знал и не думал о возможности использования «Me» в WSH, поскольку был свято уверен, что сие есть прерогатива сугубо «больших» ЯВУ — VB, VBA и т.п.

10 (изменено: wisgest, 2014-03-06 19:05:36)

Re: JScript: гибрид WSH и NET

greg zakharov пишет:

Странно, что только сейчас о JScript.NET задискутировали.

Для тормозов вроде меня — в самый раз. Исходное сообщение нахожу полезным.

wisgest пишет:

Насчёт прототипного наследования я, похоже, ошибся…

Скорее, не ошибся — с пользовательскими объектами работает. Просто первоначально я попробовал расширить через прототип Object и Number, а это нельзя, возможно, из-за того, что названия стандартых типов служат псевдонимами типов .NET.

11

Re: JScript: гибрид WSH и NET

2alexii
Когда в MSDN или книге я не находил ответов на свои вопросы, то просто брался экспериментировать с кодом. И потом, опыт зависит от настойчивости и времени.

wisgest пишет:

Исходное сообщение нахожу полезным.

Кесарю - кесарево, верно?

wisgest пишет:

Скорее, не ошибся...

Хотите по-настоящему полезный совет? Сравните скомпилированный WSH и чистый JScript.NET в IL DASM'е, а также пропустите обе сборки через mdbg, - это позволит быстро разобраться что к чему.

12

Re: JScript: гибрид WSH и NET

greg zakharov, дело в том, что я и не искал ответов.

greg zakharov пишет:

Кесарю - кесарево, верно?

«Если звёзды зажигают…»

13 (изменено: badik, 2014-03-07 06:52:03)

Re: JScript: гибрид WSH и NET

Критика должна быть констуктивной и созидательной.
Владелец кошелька (Яндекс.Деньги 410012070594869) отдает предпочтение Powershell -  это его право.
Не использовать Powershell это МОЁ право.

Здесь я пытался затронуть быструю, мягкую, по необходимости миграцию на NET.
в интернете слишком мало примеров упаковки кода WSH В NET.

У каждого своя ниша, со скелетом в шкафу.Я использую Jscript для:

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

Скрипт для решения проблемы пишется на ходу и пришивается на живую.
Срок жизни скриптов от нескольких часов до ...
У меня есть работающие  скрипты  с 2006 года. Для ускорения работы пришлось их улучшать в этом году . Тесты здесь

Два года назад мне пришлось срочно за неделю переделать два десятка скриптов.


Раньше говорили: Свобода программиста ограничена компилятором. Теперь требованиями безопасности .

14

Re: JScript: гибрид WSH и NET

badik пишет:

Критика должна быть констуктивной и созидательной.

Согласен, если эта критика не касается чужих кошельков

badik пишет:

...предпочтение Powershell...

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

badik пишет:

Здесь я пытался затронуть быструю, мягкую, по необходимости миграцию на NET.

Уважаемый, Вы противоречите самому себе. Разве не Вы писали ранее, что:

badik пишет:

Но теперь по требованию безопасности необходимо защитить код от изменений...

Так что из сего двух является истиной?

badik пишет:

У каждого своя ниша, со скелетом в шкафу.

Не стоит обобщать, лучше отвечайте за себя.

badik пишет:

Я использую Jscript для:...

Сердечно за Вас рад. Ну, а раз Вы желаете конструктивной критики, давайте посмотрим на следующий код.

with (new ActiveXObject('WScript.Shell')) {
  print(ExpandEnvironmentStrings('%USERNAME%'));
}

import System;
Console.WriteLine(Environment.GetEnvironmentVariable('USERNAME'));

Собираем его командой:

jsc.exe /nologo /t:exe /debug+ /print+ source.js

И запускаем готовый source.exe, - при этом мы не использовали условную компиляцию и прочий мусор, который бы только усложнил дальнейшую отладку кода. JScript.NET вполне допускает комбинирование WSH с управляемыми функциями.

with (new ActiveXObject('WScript.Shell')) {
  var res = ExpandEnvironmentStrings('%USERNAME%');
}

import System;
Console.WriteLine(res);

То есть для перенаправления в стандартный поток вывода не обязательно использовать WScript.echo, достаточно использовать print или Console.Write(WriteLine).
Шагаем далее.
Почему компилировать WSH с помощью jsc.exe дурная затея? На то лично у меня масса контраргументов, перечислять которые равносильно написанию научного труда, поэтому советую лишь изучить сборку из примера выше в IL DASM (см. скриншот)
http://savepic.org/5164304.jpg

15

Re: JScript: гибрид WSH и NET

Написание скриптов с нуля и миграция на другой диалект язык это две разные задачи.
Для миграции типична работа с унаследованным кодом и здесь без Условной компиляции приходится тяжело.
Переписывать заново, ради чистоты кода,25 работающих скриптов общим объемом 12 тысяч 900 строк как-то не хотелось.

Этот код

@if( @_jscript_version >= 7 )
@set @js_dotnet = 1
@else
@set @js_dotnet = 0
@end
function __print( txt )
{
    @if( @js_dotnet )
    print("NET:"+ txt );
    @else
    WScript.Echo("WSH:"+txt );
    @end
}
__print(@_jscript_version)

выполнит разные функции и вернет разные значения:

a.v2.exe
NET:8
a.v4.exe
NET:10
cscript //nologo a.js
WSH:5.8

16 (изменено: greg zakharov, 2014-03-07 11:31:32)

Re: JScript: гибрид WSH и NET

Вам про Фому, а Вы про Ерему. Смысл продолжать разговор на в общем-то бесполезную тему - извне, так что лучше уж со стороны понаблюдать за тем, как сызнова изобретается колесо.

17

Re: JScript: гибрид WSH и NET

А я хоть и читал литературу по JScript.NET, но так и не проникся им, пока не попалась задача изменения даты и времени создания/изменения/доступа файлов.

greg zakharov, хоть капитан очевидность подсказывает, что это не новая технология и  налицо еще одно открытие Америки, но думаю эту тему полезно затронуть на нашем форуме. Например, я (может и не умею гуглом пользоваться) так и не нашел нормального ресурса по этому языку. Все ударились в C#, VB.NET.

Поэтому, badik, я Вас поддерживаю. И буду рад сам поплнять примеры решения задач с учетом наличия компилятора jsc.

В принципе всегда рад неформальному общению. Если есть о чем поговорить, то Jabber + OTR, icq - на худой конец (в литературном смысле этого слова).

18 (изменено: greg zakharov, 2014-03-07 21:46:26)

Re: JScript: гибрид WSH и NET

JSman, при всем уважении: все - это кто? Обобщение есть признак субъективности (а порой и предвзятости или неприязни). Если быть предельно объективным, то обычно предпочтение тому или иному языку отдается относительно простоты восприятия синтаксиса, скорости разработки, а также тому, что проще и быстрей освоить. Например, мне не особенно нравится Python с его "голландским" синтаксисом, но это не значит что язык плох и вовсе не пригоден для использования, - в некоторых случаях он более практичен, нежели любой другой язык. Впрочем, это уже все риторика.

JSman пишет:

...так и не нашел нормального ресурса по этому языку.

Какбы есть MSDN, в смысле оффлайн версия для VS 2k8, там по JScript.NET достаточно информации. Плюс ко всему прочему, могу вообще предложить открыть отдельную ветку по оному языку, куда бы я за раз мог бы накидать с десяток другой примеров. Правда пришлось бы привести их в соответсвующий вид (с учетом безопасности).

JSman пишет:

В принципе всегда рад неформальному общению.

Аналогично. Вот только IRC по всей видимости так и будет не особо модным.

19 (изменено: badik, 2014-03-11 07:37:07)

Re: JScript: гибрид WSH и NET

1.Возьмем за основу код   Тест2
код при добавлении 1 000 000 узлов XML расходует громадное количество оперативной памяти больше 1.2G
размер последнего XML файла 51 Мб

2.Меньше чем за минуту делаем оболочку для NET тестируем

+ гибрид
@if( @_jscript_version >= 7 )
@set @js_dotnet = 1
@else
@set @js_dotnet = 0
@end

@if( @js_dotnet )
import System;
import System.IO;
@end



function _print( txt )
{
    @if( @js_dotnet )
    print( txt );
    @else
    WScript.Echo( txt );
    @end
}


var fso = new ActiveXObject("Scripting.FileSystemObject")
var logFile = fso.OpenTextFile("test_2_3.log", 8, true)
alert("Версия:"          +@_jscript_version)
alert("scripting engine:"+@_jscript_build)

var aStep = [10, 15, 25, 50, 150]
var MaxNode = 0
for (var z = 0; z < aStep.length; z++) {
  MaxNode += (aStep[z] * 1000)
  alert("узлов:" + MaxNode)
  var tt = new Date()
  var t = new Date()
  var dom = loadDom("test.xml")

  alert("1. Read XML         :" + time(t))

  var r = dom.documentElement
  t = new Date()
  var o_i = {}
  var a_i = []
  var sPath = "//e"

  t = new Date()
  var oNodes = dom.selectNodes(sPath);
  alert("2.0       Count Node:" + (oNodes.Count||oNodes.length))

  for (var i = 0; i < oNodes.length; i++) {
    var e = oNodes[i]
    o_i[[e.getAttribute("i"), e.getAttribute("k"), e.getAttribute("l")].join("|")] = i
    a_i[i] = oNodes[i].parentNode.removeChild(oNodes[i]);

  }
  alert("2. Create index Node:" + time(t))

  for (var j = 0; j < MaxNode * 4; j++) {
    i = Math.round(Math.random() * MaxNode)
    e = null
    var e_num = -1
    var x = [i, i % 3, i % 7].join("|")
    if (o_i[x] == null) {
      o_i[x] = a_i.length
      e = dom.createElement("e")
      e.setAttribute("i", i)
      e.setAttribute("k", i % 3)
      e.setAttribute("l", i % 7)
      e.setAttribute("s", "0")
      a_i[a_i.length] = e
    }
    e_num = o_i[x]
    e = a_i[o_i[x]]

    e.setAttribute("s", (1 * e.getAttribute("s")) + 1)
    var f = e.appendChild(dom.createElement("f"))
    f.setAttribute("ii", i)
    f.setAttribute("t", j)

    o_i[[e.getAttribute("i"), e.getAttribute("k"), e.getAttribute("l")].join("|")] = e_num < 0 ? r.childNodes.length - 1 : e_num
  }
  alert("3. Append Node      :" + time(t))
  t = new Date()

  for (var j = 0; j < a_i.length; j++) {
    r.appendChild(a_i[j])
  }

  alert("4. Create XML       :" + time(t) + lNode(dom))

  dom.save("test.xml")
  alert("5. Save XML         :" + time(t))
  alert("               total:" + time(tt))
  alert("")

  fso.CopyFile("test.xml", "t." + MaxNode + ".xml")

}

function alert(x) {
  _print(x)
  logFile.WriteLine(x)
}

function loadDom(xFile) {
  var dom
  dom = new ActiveXObject("msxml2.DOMDocument.6.0");
  dom.async = false;
  dom.validateOnParse = false;
  dom.resolveExternals = false;
  if (!dom.load(xFile)) {
    dom.appendChild(dom.createProcessingInstruction("xml", "version='1.0' encoding='windows-1251'"))
    dom.appendChild(dom.createElement("root"))
  }
  dom.setProperty("SelectionLanguage", "XPath")
  return dom
}

function time(t) {
  var tt = new Date()
  var d = (new Date(tt - t))
  d.setMinutes(d.getMinutes() + d.getTimezoneOffset())
  return ("" + r(d.getHours()) + ":" + r(d.getMinutes()) + ":" + r(d.getSeconds()) + "." + d.getMilliseconds())

    function r(d) {
      var s = "00" + d
      return (s.substr(s.length - 2, 2))
    }
}

function lNode(dom) {
  var sPath = "//e"
  var oNodes = dom.selectNodes(sPath);
  return (" узлов:" + oNodes.length)
}

01:57.625 system32\cscript.exe a-test.22.js
01:04.141 SysWOW64\cscript.exe a-test.22.js
03:08.188 v2.0.50727\jsc.exe /platform:x86  a-test.22.js
04:34.374 v2.0.50727\jsc.exe  a-test.22.js
02:45.453 v4.0.30319\jsc.exe /platform:x86  a-test.22.js
04:01.828 v4.0.30319\jsc.exe  a-test.22.js

3. Заменяем внешний объест msxml2.DOMDocument.6.0 на встроенный в NET XmlDocument.
Оба объекта имеют примерно одинаковый набор методов и свойств.
Для регистрозависимого языка Jscript есть неприятный сюрприз: в NET наименования начинаются с большой буквы.
Переделываем 100 строк кода, добавляем по требованию компилятора типы переменных. Тратим на это  20 минут

+ NET вариант 1
@if( @_jscript_version >= 7 )
@set @js_dotnet = 1
@else
@set @js_dotnet = 0
@end

@if( @js_dotnet )
import System;
import System.Threading;
import System.IO;
import System.Xml;
@end


function _print( txt )
{
    @if( @js_dotnet )
    print( txt );
    @else
    WScript.Echo( txt );
    @end
}

var fso = new ActiveXObject("Scripting.FileSystemObject")
var logFile = fso.OpenTextFile("test_2_3.log", 8, true)

alert("Версия:"          +@_jscript_version)
alert("scripting engine:"+@_jscript_build)

var aStep = [10, 15, 25, 50, 150]
var MaxNode = 0
for (var z = 0; z < aStep.length; z++) {
  MaxNode += (aStep[z] * 1000)
  alert("узлов:" + MaxNode)
  var tt = new Date()
  var t = new Date()
  var dom:XmlDocument = loadDom("test.xml")

  alert("1. Read XML         :" + time(t))

  var r = dom.DocumentElement
  t = new Date()
  var o_i = {}
  var a_i = []
  var sPath = "//e"

  t = new Date()
  var oNodes = dom.SelectNodes(sPath);
  alert("2.0       Count Node:" + oNodes.Count)

  for (var i = 0; i < oNodes.length; i++) {
    var e = oNodes[i]
    o_i[[e.GetAttribute("i"), e.GetAttribute("k"), e.GetAttribute("l")].join("|")] = i
    a_i[i] = oNodes[i].ParentNode.RemoveChild(oNodes[i]);

  }
  alert("2. Create index Node:" + time(t))

  for (var j = 0; j < MaxNode * 4; j++) {
    i = Math.round(Math.random() * MaxNode)
    e = null
    var e_num = -1
    var x = [i, i % 3, i % 7].join("|")
    if (o_i[x] == null) {
      o_i[x] = a_i.length
      e = dom.CreateElement("e")
      e.SetAttribute("i", i)
      e.SetAttribute("k", i % 3)
      e.SetAttribute("l", i % 7)
      e.SetAttribute("s", "0")
      a_i[a_i.length] = e
    }
    e_num = o_i[x]
    e = a_i[o_i[x]]

    e.SetAttribute("s", (1 * e.GetAttribute("s")) + 1)
    var f = e.AppendChild(dom.CreateElement("f"))
    f.SetAttribute("ii", i)
    f.SetAttribute("t", j)

    o_i[[e.GetAttribute("i"), e.GetAttribute("k"), e.GetAttribute("l")].join("|")] = e_num < 0 ? r.ChildNodes.length - 1 : e_num
  }
  alert("3. Append Node      :" + time(t))
  t = new Date()

  for (var j = 0; j < a_i.length; j++) {
    r.AppendChild(a_i[j])
  }

  alert("4. Create XML       :" + time(t) + lNode(dom))

  dom.Save("test.xml")
  alert("5. Save XML         :" + time(t))
  alert("               total:" + time(tt))
  alert("")

  fso.CopyFile("test.xml", "t." + MaxNode + ".xml")

}

function alert(x) {
  _print(x)
  logFile.WriteLine(x)
}

function loadDom(xFile) {
  var dom:XmlDocument = new XmlDocument();;
  //dom.Async = false;
  //dom.ValidateOnParse = false;
  //dom.ResolveExternals = false;
  if (!fso.FileExists(xFile)) {
    dom.AppendChild(dom.CreateProcessingInstruction("xml", "version='1.0' encoding='windows-1251'"))
    dom.AppendChild(dom.CreateElement("root"))
  } else {

  dom.Load(xFile)
 }
//  dom.SetProperty("SelectionLanguage", "XPath")
  return dom
}

function time(t) {
  var tt = new Date()
  var d = (new Date(tt - t))
  d.setMinutes(d.getMinutes() + d.getTimezoneOffset())
  return ("" + r(d.getHours()) + ":" + r(d.getMinutes()) + ":" + r(d.getSeconds()) + "." + d.getMilliseconds())

    function r(d) {
      var s = "00" + d
      return (s.substr(s.length - 2, 2))
    }
}

function lNode(dom) {
  var sPath = "//e"
  var oNodes = dom.SelectNodes(sPath);
  return (" узлов:" + oNodes.Count)
}

02:42.657 v2.0.50727\jsc.exe /platform:x86  a-test.n.js
02:53.797 v2.0.50727\jsc.exe  a-test.n.js
02:32.844 v4.0.30319\jsc.exe /platform:x86  a-test.n.js
02:27.093 v4.0.30319\jsc.exe  a-test.n.js

4. Не понравилось время получененое в предыдущем примере.
Эксперементировал 20  минут: 

+ NET вариант 2

***** было
  for (var i = 0; i < oNodes.length; i++) {
    var e = oNodes[ i ]
***** стало
  for (var i = 0; i < oNodes.Count; i++) {
    var e:XmlElement = oNodes[ i ]
*****
***** было
    var f = e.AppendChild(dom.CreateElement("f"))
    f.SetAttribute("ii", i)
    f.SetAttribute("t", j)
***** стало
    var f:XmlElement=dom.CreateElement("f")
    f.SetAttribute("ii", i)
    f.SetAttribute("t", j)
    e.AppendChild(f)
*****

@set @js_dotnet = 1

import System;
import System.Threading;
import System.IO;
import System.Xml;

var fso = new ActiveXObject("Scripting.FileSystemObject")
var logFile = fso.OpenTextFile("test_2_5.log", 8, true)

alert("Версия:"          +@_jscript_version)
alert("scripting engine:"+@_jscript_build)

var aStep = [10, 15, 25, 50, 150]
var MaxNode = 0
for (var z = 0; z < aStep.length; z++) {
  MaxNode += (aStep[z] * 1000)
  alert("узлов:" + MaxNode)
  var tt = new Date()
  var t = new Date()
  var dom:XmlDocument = loadDom("test.xml")

  alert("1. Read XML         :" + time(t))

  var r = dom.DocumentElement
  t = new Date()
  var o_i = {}
  var a_i =[]
  var sPath = "//e"

  t = new Date()
  var oNodes= dom.SelectNodes(sPath);
  alert("2.0       Count Node:" + oNodes.Count)

  for (var i = 0; i < oNodes.Count; i++) {
    var e:XmlElement = oNodes[i]
    o_i[[e.GetAttribute("i"), e.GetAttribute("k"), e.GetAttribute("l")].join("|")] = i
    a_i[i] = oNodes[i].ParentNode.RemoveChild(oNodes[i]);

  }
  alert("2. Create index Node:" + time(t))

  for (var j = 0; j < MaxNode * 4; j++) {
    i = Math.round(Math.random() * MaxNode)
    e = null
    var e_num = -1
    var x = [i, i % 3, i % 7].join("|")
    if (o_i[x] == null) {
      o_i[x] = a_i.length
      e = dom.CreateElement("e")
      e.SetAttribute("i", i)
      e.SetAttribute("k", i % 3)
      e.SetAttribute("l", i % 7)
      e.SetAttribute("s", "0")
      a_i[a_i.length] = e
    }
    e_num = o_i[x]
    e = a_i[o_i[x]]

    e.SetAttribute("s", (1 * e.GetAttribute("s")) + 1)
    var f:XmlElement=dom.CreateElement("f") 
    f.SetAttribute("ii", i)
    f.SetAttribute("t", j)
    e.AppendChild(f)

    o_i[[e.GetAttribute("i"), e.GetAttribute("k"), e.GetAttribute("l")].join("|")] = e_num < 0 ? r.ChildNodes.length - 1 : e_num
  }
  alert("3. Append Node      :" + time(t))
  t = new Date()

  for (var j = 0; j < a_i.length; j++) {
    r.AppendChild(a_i[j])
  }

  alert("4. Create XML       :" + time(t) + lNode(dom))

  dom.Save("test.xml")
  alert("5. Save XML         :" + time(t))
  alert("               total:" + time(tt))
  alert("")

  fso.CopyFile("test.xml", "t." + MaxNode + ".xml")

}

function alert(x) {
  print(x)
  logFile.WriteLine(x)
}

function loadDom(xFile) {
  var dom:XmlDocument = new XmlDocument();;
  //dom.Async = false;
  //dom.ValidateOnParse = false;
  //dom.ResolveExternals = false;
  if (!fso.FileExists(xFile)) {
    dom.AppendChild(dom.CreateProcessingInstruction("xml", "version='1.0' encoding='windows-1251'"))
    dom.AppendChild(dom.CreateElement("root"))
  } else {

  dom.Load(xFile)
 }
//  dom.SetProperty("SelectionLanguage", "XPath")
  return dom
}

function time(t) {
  var tt = new Date()
  var d = (new Date(tt - t))
  d.setMinutes(d.getMinutes() + d.getTimezoneOffset())
  return ("" + r(d.getHours()) + ":" + r(d.getMinutes()) + ":" + r(d.getSeconds()) + "." + d.getMilliseconds())

    function r(d) {
      var s = "00" + d
      return (s.substr(s.length - 2, 2))
    }
}

function lNode(dom) {
  var sPath = "//e"
  var oNodes = dom.SelectNodes(sPath);
  return (" узлов:" + oNodes.Count)
}

00:41.328 v2.0.50727\jsc.exe /platform:x86  a-test.n2.js
00:43.797 v2.0.50727\jsc.exe  a-test.n2.js
00:39.531 v4.0.30319\jsc.exe /platform:x86  a-test.n2.js
00:41.734 v4.0.30319\jsc.exe  a-test.n2.js

5.Время обработки: WSH 1 минута , Гибрид 2:45, NET 40 секунд.
   Скорость обработки узлов в секунду WSH 15 000 , Гибрид  7 000, NET 25 000.
В реальной жизни скрипты редко обрабатывают больше 100 000 узлов (записей) поэтому разница времении в 11 секунд (15-4) между вариантами является не критичной.
Чтобы получить максимальную скорость обработки было затрачено >40 минут на переработку и оптимизацию кода.
Полученая экономия окупится через 40*60/11 =218 рабочих дней

20

Re: JScript: гибрид WSH и NET

Всем доброго времени суток!
По роду деятельность приходится кодить либо на jscript /vbscript, (либо powershell)
Так исторически сложилось, что на jscript написаны сотни скриптов автоматизации, которые приходится поддерживать и развивать.
В логическом развитии, пришел к JScript.NET (предварительно проштудировав Джастин Роджерс) - понравилась реализации работы с XML, расчет контрольных сумм файлово и строк.
У меня, собственно два вопроса к уважаемому сообществу,
- есть ли реальные примеры реализации в JScript.NET работы с классом System.Runtime.Serialization.Json (необходимо реализовать парс json). Яростное "гугление" четких ответов/примеров не дает
- Второй вопрос, это собственно "Bypass and Restore SSL Certificate Validation in .NET". Есть примерчик на .NET. Привожу ниже:


'ByPass SSL Certificate Validation Checking
System.Net.ServicePointManager.ServerCertificateValidationCallback = _
  Function(se As Object, _
  cert As System.Security.Cryptography.X509Certificates.X509Certificate, _
  chain As System.Security.Cryptography.X509Certificates.X509Chain, _
  sslerror As System.Net.Security.SslPolicyErrors) True

'Call web application/web service with HTTPS URL

'Restore SSL Certificate Validation Checking
System.Net.ServicePointManager.ServerCertificateValidationCallback = Nothing

Как данное элегантно реализуется на JScript.NET...?
Заранее, спасибо!

21

Re: JScript: гибрид WSH и NET

NovaRo, честно признаюсь - опыта в JScript.NET у меня практически ноль, но возможно мой пример пригодится.

Недавно ковырялся с подобной задачей. Заметил, что многие рекомендуют использовать JSON.NET

Вот примерчик кода:


import System;
import System.Core;
import Newtonsoft.Json;
import Newtonsoft.Json.Serialization;
import Newtonsoft.Json.Linq;

var data = '{int:1,string:"test",date:"2019-03-03T16:48:25Z"}'

Console.WriteLine("Source string: " + data)

var object = JObject.Parse(data);

Console.WriteLine("--- Parse result ---")

Console.WriteLine(object)
Console.WriteLine("--- Properties ---")
Console.WriteLine('object.int:\t'		+ object['int']);
Console.WriteLine('object.string:\t'	+ object['string']);
Console.WriteLine('object.date:\t'		+ object['date']);

Console.WriteLine("--- Adding new property ---")

object['new'] = 'new value';

Console.WriteLine("Stringified to: " + JsonConvert.SerializeObject(object));

В аттаче запускаемый пример.

NovaRo пишет:

Второй вопрос, это собственно "Bypass and Restore SSL Certificate Validation in .NET". Есть примерчик на .NET.
...
Как данное элегантно реализуется на JScript.NET...?

Пока что предполагаю, что как-то так:


import System;
import System.Net.Security;
import System.Security.Cryptography.X509Certificates;

class CallbackClass {
	static function Callback(
		se			:Object
		,cert		:X509Certificate
		,chain		:X509Chain
		,sslError	:SslPolicyErrors): boolean
	{
		return true
	}
}

System.Net.ServicePointManager.ServerCertificateValidationCallback = CallbackClass.Callback

Но проверить не на чем.

А на целиковый код примера можно взглянуть ?

Post's attachments

JSON_TEST.rar 165.33 kb, 1 downloads since 2019-03-03 

You don't have the permssions to download the attachments of this post.
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

22

Re: JScript: гибрид WSH и NET

Спасибо большое Вам, за примеры!
С коллбэками ещё не приходилось работать) Очень элегантная у вас реализация получилась!
Ещё раз, спасибо и за пример с json!

23

Re: JScript: гибрид WSH и NET

NovaRo, рад, что пригодилось, но не спешите благодарить ). Я ещё не уверен, что код:
а) Правильно написан (он конечно запускается и в консоль всё выводит, но наверняка можно гораздо проще всё это сделать)
б) Правильно работает

Сегодня первый день как я решил поизучать принципы работы с JScript.NET / VBScript.NET, поэтому наверняка косячу.

Касательно сериализации JSON, вот тут неплохо разобрано как можно налету подготавливать данные для сериализации. Там ниже по тексту много разных примеров.

По поводу callback-а информацию тут взял: ссылка

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

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !