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

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 задискутировали.

8

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

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

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

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

greg zakharov пишет:

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

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

wisgest пишет:

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

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

10

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

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

wisgest пишет:

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

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

wisgest пишет:

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

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

11

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

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

greg zakharov пишет:

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

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

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

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

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

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

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

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

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

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


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

13

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

14

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

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

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

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

16

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

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

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

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

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

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

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

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

JSman пишет:

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

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

JSman пишет:

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

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

18 (изменено: 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 рабочих дней

19

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...?
Заранее, спасибо!

20

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, 4 downloads since 2019-03-03 

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

21

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

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

22

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

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

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

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

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

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

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

23

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

Всем доброго времени!
Извиняюсь, что не надолго выпал из темы)
В общем, отписываюсь по результатам - собственно:
1). Ваш вариант с callback ("Bypass and Restore SSL Certificate Validation") - работает замечательно! Так что как говорится, "маст хев" к использованию!
2). На счет Json, - работу библиотеки JSON.NET, пока не получилось проверить. Но, нашел не менее элегантный вариант т.с. "штатным инструментарием":
вариант для Javascript

// classic WSH JScript version
var htmlfile = new ActiveXObject('htmlfile'), JSON;
htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
htmlfile.close(JSON = htmlfile.parentWindow.JSON);
вариант для JScript.NET

вариант для JScript.NET


// JScript.NET version
var htmlfile:Object = new ActiveXObject('htmlfile'), JSON:Object = {};
htmlfile.IHTMLDocument2_write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
htmlfile.close(JSON = htmlfile.parentWindow.JSON);

ниже привожу рабочий кусок кода:


import System;
import System.Collections.Generic;
import System.Linq;
import System.Web;
import System.Runtime.Serialization.Json;
import System.IO;
import System.Text;
import System.IO.UnmanagedMemoryStream;
public class saveJson {
public static function Main(Args:String[]) : void {

var htmlfile:Object = new ActiveXObject('htmlfile'), JSON:Object = {};
htmlfile.IHTMLDocument2_write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
htmlfile.close(JSON = htmlfile.parentWindow.JSON);
var value = JSON.stringify('{ "Request":"APP_PROFILE_GET","Properties":{"AppName":"all"}}');
var jsontext = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}';
var contact = JSON.parse(jsontext);
var fullname = contact.surname + ", " + contact.phone[1];
Console.WriteLine(fullname);
Console.WriteLine(value);
}
}
saveJson.Main(Environment.GetCommandLineArgs());

24

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

Рад, что смог помочь.

На счёт нативной сериализации и десериализации (без сторонних библиотек) есть такой вариант:


import System;
import System.Web.Extensions;
import System.Web.Script.Serialization;

var serializer = new JavaScriptSerializer();

// Десериализация
var items = serializer.DeserializeObject('{\
	"firstname":"Jesper",\
	"surname":"Aaberg",\
	"phone":["555-0100","555-0120"]\
}')

Console.WriteLine(items("firstname") + ' ' + items("surname"))

// Сериализация
class Rectangle {
	var color:String;
	var width:Number;
	var height:Number;
}
var rect = new Rectangle()
with(rect){
	color = 'red'
	width = 100
	height = 100
}

Console.WriteLine(serializer.Serialize(rect));

И ещё вот так можно


import System;
import System.Web.Extensions;
import System.Web.Script.Serialization;

var serializer = new JavaScriptSerializer();

var items = serializer.DeserializeObject('{a:1,b:2,c:{d:1}}')

items("a") = 100
items("b") = 'test'
items("c")("d") = 200

Console.WriteLine(items("a") + ' ' + items("b"))

Console.WriteLine(serializer.Serialize(items))
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

25

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

На счет Json, - работу библиотеки JSON.NET, пока не получилось проверить.

Отчитываюсь - библиотечка работает, функционал отличный, даже с избытком. Вот полное описание функционала:https://www.newtonsoft.com/json/help/ht … uction.htm
привожу рабочий пример:

import System;
import System.Core;
import Newtonsoft.Json;
import Newtonsoft.Json.Serialization;
import Newtonsoft.Json.Linq; 
import JScript.NET.Samples;
package JScript.NET.Samples {
public class saveJson {
public static function Main(Args:String[]) : void {
var jsontext = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}';
Console.WriteLine("Source string: " + jsontext)

var object = JObject.Parse(jsontext);

var date = (object['phone'][0] + " "+ object['firstname']);

Console.WriteLine("--- Parse result ---")
Console.WriteLine("Stringified to: " + JsonConvert.SerializeObject(object));
}
}
}
saveJson.Main(Environment.GetCommandLineArgs());

Обратите внимание, что выбор элемента Jsona здесь реализован иначе:
date = (object['phone'][0] + " "+ object['firstname'])

26

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

NovaRo, на всякий случай, взгляните на мой предыдущий пост. Там про вариант работы с JSON средствами встроенными в NET. Вдруг тоже будет полезно.

P.S А не расскажете - какая конечная цель ? Что за проект собираете ?

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

27

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

Xameleon

А не расскажете - какая конечная цель ?

Да, собственно, ни чего "военного", - по-сути, проект по автоматизации определенных действий, с "фид-бэком" результатов выполнения / отработки, на сервер-инициатор, через webRequest. Для удобства, обмен реализован в json (часть в XML-формате)
Есть определенный парк удаленных машин (платежных терминалов) суммарно, ~1000 устройств. Проект, по-сути представляет из себя клиента, внутри которого набор (коллекция) функций, которые  выполняются, в зависимости от параметра, через передачу аргумента на входе.
Например, собрать определенные данные из логов (инвнтаризация) и отправить  на сервер, либо наоборот, выполнить команду: скачать и установить недостающий пакет (с сервера обновления), выполнить чек-диск, смена IP, архивацию логов запрошлый день, ну и в таком духе.
Изначально, все писалось на javascript, но потом проект перерос себя, и встала задача расширить функционал (например, отдельной функцией можно проверить .MD5 строки, файла, содержимого каталога). Т.е. подключив практически любую библиотеку .NET, можно "наворачивать" функционал почти без ограничений. Да, это не полноценное .NET-приложение, но со своими задачами справляется.
Что еще из интересного - это была попытка создать гибриды C# + Powershell. Проекты, условно рабочие, но дальше концепт-версий дело не пошло. Привлекает то, что в одном проекте, можно использовать всю мощь C#, гибкость и простоту Powersell (огромное кол-во уже готовых скриптов!) и любые классы WMI..!

28

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

1) Понял. Очень интересный проект. Если будет возможность - похвастайтесь потом наработками, пожалуйста. Можно даже в личку. Мне в образовательных целях интересно, так как с JScript.NET вообще опыта кодинга не имею.

2) Кстати, вариант с JavaScriptSerializer не пригодился ?

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

29

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

Всем доброго времени суток! Извиняюсь за долгое отсутствие в теме - срочно пришлось заниматься другими проектами.
Отписываюсь по результатам:
- Вариант с библиотекой JSON.NET, пока использую ограниченно - только на новых системах под Win7. Работает отлично - нареканий пока нет. С большим заделом на будущее.
- На основной массе устройств (под Win XP) использую вариант

var htmlfile:Object = new ActiveXObject('htmlfile'), JSON:Object = {};
htmlfile.IHTMLDocument2_write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
htmlfile.close(JSON = htmlfile.parentWindow.JSON);

т.к. не требует ни каких лишних телодвижений, и работает стабильно "из коробки", даже из "чистого" скрипта без компиляции. Хотя, в компилируемом варианте, под JScript.NET, тоже - без вопросов!

Xameleon пишет:

1) 2) Кстати, вариант с JavaScriptSerializer не пригодился ?

Честно - пока не юзал, но в любом случае, спасибо большое за пример реализации! Весьма лаконично и "штатными ср-ми", как говорят! Обязательно пригодится!!

Сейчас стал вопрос немного в другом - необходимо преобразовывать большие  JSON_объекты в массивы, для последующего разбора, "парсинга" и анализа. Пока однозначного решения не нашел. Пробую вариант JSON.parse(str, reviver)  - там есть второй параметр reviver, который является функцией function(key, value):

// дата в строке - в формате UTC
var str = '{"title":"Конференция","date":"2014-11-30T12:00:00.000Z"}';

var event = JSON.parse(str, function(key, value) {
  if (key == 'date') return new Date(value);
  return value;
});
alert( event.date.getDate() ); // теперь сработает!

НО, как получить в массив весь JSON-объект и рекурсивно обработать (например, через FOR) все в виде "ключ - значение" (по принципу key[k] = value[k]) особенно в случае, когда количества "ключей" в JSON-объекте не известно?
Например:

var str = '{"title":"Конференция","date":"2014-11-30T12:00:00.000Z"; "title":"Заседание","date":"2014-11-30T16:00:00.000Z"}';
var event = JSON.parse(str)

event.length  - ни чего не возвращает....

30

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

Кстати, во такой вариант, тоже не работает:


var contact = new Array();
contact = JSON.parse(responsedata, function(key, value) {
Console.WriteLine(key+ " " +value);
return [key, value];       // возвращаем неизменённое значение свойства
}
);
Console.Write(contact.length);

contact - не является объектом((

Необработанное исключение: Microsoft.JScript.JScriptException: Требуется объект
Требуется объект
   в Microsoft.JScript.Convert.ToObject(Object value, VsaEngine engine)
   в JScript.NET.Samples.saveJson.Main(String[] Args) в test.js:строка 163
   в JScript 0.Global Code() в test.js:строка 198
   в JScript Main.Main(String[] )

Хотя, внутри функции, я все отлично получаю - проблем в том, как передать наружу значения [key, value] в виде массива.

31

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

NovaRo, дык правильно. ) У Вас в JSON коде ошибка

var str = '{"title":"Конференция","date":"2014-11-30T12:00:00.000Z"; "title":"Заседание","date":"2014-11-30T16:00:00.000Z"}';

1) Поля JSON объекта разделяются только запятой.
2) Ваш код не возвращает никаких ошибок, скорее всего, потому что не подключен обработчик ошибок.


window.onerror = function(e){
	Console.WriteLine(e)
}

Хотя я бы всё-таки порекомендовал использовать встроенные средства NET для парсинга либо всё-таки Json.NET если он Вам удобнее.
Наверное, как-нибудь так:


import System;
import System.Web.Extensions;
import System.Web.Script.Serialization;

(function(){
	// Создание сериализатора/десериализатора
	var serializer = new JavaScriptSerializer();
	// Подготовка данных
	var data = '[\
			{\
				"title":"Конференция",\
				"date":"2014-11-30T12:00:00.000Z"\
			},{\
				"title":"Заседание",\
				"date":"2014-11-30T16:00:00.000Z",\
				"somedata":"test"\
			},{\
				"title":"Заседание2",\
				"date":"2014-11-30T18:00:00.000Z"\
			}\
	]';

	var items = [];
	try {
		//Разбор данных с обработкой ошибок
		items = serializer.DeserializeObject(data);
	} catch(e){
		Console.WriteLine(e);
		return
	}

	var item, keys;
	// Перебор элементов массива
	for(var i in items){
		// Получение элемента массива
		item = items[i];
		// Получение списка ключей элемента
		keys = item.Keys;
		// Перебор ключей и вывод их значений
		for(var key in keys){
			Console.WriteLine(key + ': "' + item(key) + '"');	
		}
	}
})();
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

32

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

Пока ни чего не выходит... Бьет ошибку еще на этапе компиляции  ((

var serializer = new JavaScriptSerializer();

Самое непонятное, почему я не могу получить данный из функции:

contact = JSON.parse(responsedata, function(key, value) {
Console.WriteLine(key+ " " +value);
return [key, value];       // возвращаем неизменённое значение свойства
}
);
Console.Write(contact.length);

Я же вижу, что Console.WriteLine(key+ " " +value) - возвращаются данные, - а на выходе из функции пусто(
System.Console.WriteLine(key) - пусто....

33

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

NovaRo

Пока ни чего не выходит... Бьет ошибку еще на этапе компиляции  ((

А Namespace-ы подключили ? Мой целиковый пример срабатывает ?

Самое непонятное, почему я не могу получить данный из функции:

Ох не даёт Вам покоя этот способ разбора.

Думаю, что проблема в том, что Вы передаёте в JSON.parse ссылку на функцию, которая сформирована во внешнем коде (как объект) (Заметил, что такая ситуация наблюдается и в NET и в WSH). По видимому внешние функции работают несколько иначе нежели функции созданные в пределах HTML документа. Поэтому, чтобы добиться того результата, который Вы хотите, пришлось воспользоваться одним из вариантов ухищрений - создать wrapper (оболочку) на функцию. Что, лично я, не приветствую. Но возможно есть и более простые способы.


import System;

// Функция создания HTML документа
function createHTMLDocument(version){
	var document = new ActiveXObject('htmlfile');
	var e = document.createElement('meta');
	e.setAttribute('http-equiv','x-ua-compatible');
	e.setAttribute('content','ie=' + version)
	if(document.IHTMLDocument2_write){
		document.IHTMLDocument2_write(e.outerHTML);
	} else {
		document.write(e.outerHTML);
	}
	return document
};

// Формирование документа в режиме максимальной версии
var document = createHTMLDocument("Edge")
// Получение ссылки на родительский объект окна
var window = document.parentWindow
// Получение ссылки на JSON объект
var JSON = window.JSON
// Создание функции, которая будет делать обёртку на NET функцию
window.eval('function createReviverWrap(fn){return function(key,value){return fn(key,value)}}')

	
try {
	// Подготовка данных
	var data = '[{"title":"Конференция","date":"2014-11-30T12:00:00.000Z"},{"title":"Заседание","date":"2014-11-30T16:00:00.000Z"}]'
	
	// Разбор данных
	var object = JSON.parse(data,window.createReviverWrap(function(key,value){
		Console.WriteLine(key + ': ' + value)
		return value
	}))
	
	Console.WriteLine('--------------------')
	
	// Сборка объекта в текстовое представление и вывод результата
	Console.WriteLine(JSON.stringify(object,,'\t'))
	
} catch(e){
	Console.WriteLine('JSON parse error. ' + e);
}
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

34

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

Подскажите, а есть-ли интерпретатор .NET?

Как cmd или Powershell.

Или надо обязательно компиллировать?

35

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

Parazit, насколько мне известно, к сожалению, встроенного в Windows нет, но есть скомпилированные на NET в виде COM объектов и в виде exe модулей.

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

36

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

Xameleon
Доброго времени суток! Отписываюсь по результатам рабочего дня: Ваш вариант с  wrapper, работает отлично!
Теперь есть возможность "нативной" конвертации JSON-объекта в массив, и соответственно, "по-элементный" разбор  каждой пары key-value.
Спасибо большое за помощь!
Это бы реальный мастер-класс!

37

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

Parazit
Пробовал использовать во этот аддон для студии:

Но, толком оно у меня так и не заработало... Да, и совместимо только с 15 версией студии.
Не знаю, существует ли еще альтернативные IDE-среды для работы с JScript.NET. А было бы неплохо! Уж очень удобная штучка, особенно

38

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

Xameleon
Еще раз, хочу сказать спасибо, за Вашу неоценимую помощь! Как говорится, -  "сколько умных книжек не читай...", а мастерство таких профи, как Вы - сложно переоценить! В очередной раз убедился, на сколько важно знать и уметь использовать всю мощь и гибкость любого языка программирования! + недокументированные возможности, имхо! Надеюсь, Ваше решение (как и мне) сэкономит кому-нибудь еще время и нервы! Уверен в этом!)
Однозначно,  в "копилочку знаний" форума.
P.S.

+ открыть спойлер

чуть позже, выложу итоговый ("причесанный") релиз того, что у меня получилось - с макс. комментариями к коду, как демонстрация возможности JScript.Net в плане работы с JSON.

P.P.S. К слову, работа с XML в JScript.Net "из коробки" реализована достаточно полно - вопросов не возникало.

39

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

А без .Net, на «гольном» JScript/VBScript возможно преобразование текстового JSON в массив/коллекцию?

40

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

alexii,

https://www.json.org/

Прокрутите страницу до самого низа. Там множество вариантов реализация для разных языков.

Для чистого JS: https://github.com/douglascrockford/JSON-js

Для VBS подойдёт вариант, который использовался выше в этой теме. Либо использование json2.js в соединении через WSC / WSF.

NovaRo, я бы всё-таки порекомендовал использовать нативные способы. ) В частности разобраться с JavaScriptSerializer

Я рад, что смог Вам помочь с кодом, но мне кажется, что радоваться рано. Это решение, как говорится "по бедности" и наверняка может быть реализовано правильнее. К сожалению, как я уже говорил, я очень плохо знаю возможности JScript.NET и потому сделал так. Но однозначно уверен, что использование родных NET-овских объектов в среде NET будет работать оптимальнее.

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

41

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

Кстати, как оказалось, я немного рано радовался -  всплыл еще один неприятный момент,  - под Net2.0 именно на ХР (на Win7, под тем же Net2.0 все работает отлично)
конструкции вида:

htmlfile.IHTMLDocument2_write('<meta http-equiv="x-ua-compatible" content="IE=8" />');
window.eval('function createReviverWrap(fn){return function(key,value){return fn(key,value)}}'); 

не работают корректно... ( Код компилируется, но при запуске скрипта, одна и та же ошибка:
Видимо, это как-то связано с особенностью компилирования именно под XP... Вот такой оборот....

+ открыть спойлер

Unhandled Exception: Microsoft.JScript.JScriptException: Function expected
Function expected
   at Microsoft.JScript.LateBinding.CallCOMObject(IReflect ir, String name, Object ob, Binder binder, Object[] arguments, Parame
terModifier[] modifiers, CultureInfo culture, String[] namedParameters, Boolean construct, Boolean brackets, VsaEngine engine)
   at Microsoft.JScript.LateBinding.Call(Binder binder, Object[] arguments, ParameterModifier[] modifiers, CultureInfo culture,
String[] namedParameters, Boolean construct, Boolean brackets, VsaEngine engine)
   at Microsoft.JScript.LateBinding.Call(Object[] arguments, Boolean construct, Boolean brackets, VsaEngine engine)
   at JScript.NET.Samples.CommandLineParser.Add.createHTMLDocument(Object this, VsaEngine vsa Engine, Object version)
   at JScript.NET.Samples.CommandLineParser.Add()
   at JScript 0.Global Code()
   at JScript Main.Main(String[] )

42

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

Пардон. Я у себя фиксил вроде бы вот так:


// Функция создания HTML документа
function createHTMLDocument(version){
	var document = new ActiveXObject('htmlfile');
	var e = document.createElement('meta');
	e.setAttribute('http-equiv','x-ua-compatible');
	e.setAttribute('content','ie=' + version)
	if(document.IHTMLDocument2_write){
		document.IHTMLDocument2_write(e.outerHTML);
	} else {
		document.write(e.outerHTML);
	}
	return document
};
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

43

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

Ок!
Так сработало!  в Win7  в версии Net2.0 и Net4.0 (IE 11) - работает отлично!
В XP - версия Net2.0  (IE 8)  - все равно, бьет  эксепшн на сам враппер:

window.eval('function createReviverWrap(fn){return function(key,value){return fn(key,value)}}'); 
+ открыть спойлер

Unhandled Exception: Microsoft.JScript.JScriptException: Function expected
Function expected
   at Microsoft.JScript.LateBinding.CallCOMObject(IReflect ir, String name, Object ob, Binder binder, Object[] arguments, Parame
terModifier[] modifiers, CultureInfo culture, String[] namedParameters, Boolean construct, Boolean brackets, VsaEngine engine)
   at Microsoft.JScript.LateBinding.Call(Binder binder, Object[] arguments, ParameterModifier[] modifiers, CultureInfo culture,
String[] namedParameters, Boolean construct, Boolean brackets, VsaEngine engine)
   at Microsoft.JScript.LateBinding.Call(Object[] arguments, Boolean construct, Boolean brackets, VsaEngine engine)
   at JScript.NET.Samples.CommandLineParser.Add() in test1.js:line 140
   at JScript 0.Global Code() in test1.js:line 244
   at JScript Main.Main(String[] )

44

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

NovaRo, и мой целиковый пример тоже ?

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

45

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

Xameleon
К сожалению да... И именно в XP - версия Net2.0  (IE 8)... ((

46 (изменено: Parazit, 2019-05-15 13:27:01)

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

NovaRo пишет:

window.eval('function createReviverWrap(fn){return function(key,value){return fn(key,value)}}');

А что возвращает функция fn?
У неё даже тела нет.
Как она может что-то возвратить?
Соответственно, все родительские функции тоже ничего не возвращают.
А компилятор же ждёт некие данные, и не получив их, очень злится и ругается.

47

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

Parazit, fn это переданная из NET кода ссылка на функцию, которая ложится в обёртку. Посмотрите мой код выше.

NovaRo, к сожалению пока проверить не на чем. Нет XP под рукой. Как я понял, JavaScriptSerializer работает только под NET 4.0. Поэтому предпочтение отдаю всё-таки именно Newtonsoft JSON.NET. Кстати возник вопрос - а для каких целей Вам нужен обратный вызов процедуры с обработкой key, value групп ? Почему не перебрать их уже в результирующем подготовленном объекте ?

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

48

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

Parazit
тем не менее, в Win7  в версии Net2.0  (IE 11) - прекрасно отрабатывает!) Повторюсь - Net2.0  (IE 11)

для каких целей Вам нужен обратный вызов процедуры с обработкой


Собственно, цель одна: прилетает JSON-объект, в котором коллекция (key,value) переменной длинны. Элементов более 60-ти!
Необходимо, каждую пару из  этого  JSON-объект загнать в массив, для последующего разбора. Суть в чем, - тут мне важен номер элемента массива (индекс)!
т.е., к примеру в 10 элементе, может быть значения value1.... value60 (т.е. я не знаю, какое значение там). А мне нужно взять значение этого 10 элемента, и  записать полученную пару key,value в соответствующую ветку реестра.
Для этого и нужен массив. Как-то так....)
Надеюсь, получилось донести мысль.

49

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

NovaRo,

Перечитал несколько раз, но так и не понял в чём проблема. Что мешает получать индекс элемента при переборе ?


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

var data:String = '[{ \
		"key":"Key 0", \
		"value":"A" \
	},{ \
		"key":"key 1", \
		"value":"B", \
	},{ \
		"key":"Key 2", \
		"value":"C", \
	},{ \
		"key":"Key 3", \
		"value":"D", \
	},{ \
		"key":"Key 4", \
		"value":"E", \
	},{ \
		"key":"Key 5", \
		"value":"F", \
	}]';

(function(){
	var objects:Object = {}, object:Object;
	try {
		objects = JsonConvert.DeserializeObject(data,System.Object);
	} catch(e){
		Console.WriteLine('Parse error ! ' + e.description);
		return
	}
	for(var i=0; i < objects.Count;i++){
		object = objects[i];
		Console.WriteLine(i + ') key:"' + object("key") + '", value:"' + object("value") + '"');
	}
	
	Console.WriteLine('----------------')
	
	Console.WriteLine('Reading custom item with index 4: Key "' + objects[4]("key") + '", value: "' + objects[4]("value") + '"')
	
})();
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

50

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

Да, все отлично работает!)
Просто, до этого мы разбирали варианты именно нативной работы с JSON без подключения сторонних библиотек Newtonsoft!
И ваше решение с wrapper-ом отлично работает, но увы, только в связке с Win7  и даже в версии Net2.0 ! (IE 11).
Для XP, как видите пока не выходит. Честно говоря, пока не пойму в чем загвоздка - то ли в особенности компилятора jsc под Win XP Net2.0? Хотя, стоит полноценная версия с SP3 с "фреймворком" v2.0.50727....
Чувствую, что в случае с XP, видимо придется остановиться на варианте с Newtonsoft JSON.NET. Другого выхода пока не вижу.
P.S. на Win7 (под вашим решением) сегодня запустился - работает все четко!
Еще раз, спасибо за код!

51

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

NovaRo,

Думаю всё же лучше остановиться на использовании Newtonsoft JSON, так как он работает и под FW 2.0 и 4.0. И не требует всяческих костылей при работе.

Сегодня поднял виртуалку с XP. Решил проверить в чём же беда с кодом.

Вот что выяснил:

1) На Win XP SP3 по умолчанию не нашёл Framework 2.0 и IE8. Пришлось поставить.
2) Выяснил, что строка кода с созданием функции оболочки вызывала ошибку, потому что надо было перед её вызовом инициализировать интерпретатор кода, чтобы он знал какой скрипт выполняет (JScript / VBScript):

window.execScript('function createReviverWrap(fn){return function(key,value){return fn(key,value)}}')

вместо eval(...).

В общем получилось добиться желаемого результата и с таким кодом, но.... Это явно неверный путь ).

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

52

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

Xameleon
Не перестаю удивляться вашему мастерству!)
НО, мы были на верном пути. Кстати, я пробовал вариант с window.Run - но, вот за метод exec, как-то забыл!
И еще... Если не затруднит - Вы не могли бы запустить приведенный код у себя - получаю странную ошибку:
"JSON parse error. Error: Object required"
А то я уже в растерянности - "то ли лыжи не едут... ". Где на этот раз прокол?

+ открыть спойлер
import System;
import System.IO;
import JScript.NET.Samples;
import System.Threading;
import System.Collections.IEnumerable;
import System.Net.ServicePointManager;
import System.Runtime.Serialization.Json;
import System.Collections;
import System.Management;
import System.Globalization;
import System.Xml;
import System.Net;
import System.Net.Security;
import System.Security.Cryptography.X509Certificates;
import System.Collections.Generic;
import System.Linq;
import System.Web;
import System.Web.Extensions;
import System.Web.Script.Serialization;
import System.Runtime.Serialization.Json;
import System.Text;
import System.IO.UnmanagedMemoryStream;
var Args:String[] = Environment.GetCommandLineArgs();

package JScript.NET.Samples {  

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

public class saveJson {

public static function Main(Args:String[]) : void {

function createHTMLDocument(version){
	var document = new ActiveXObject('htmlfile'), JSON:Object = {};
	var e = document.createElement('meta');
	e.setAttribute('http-equiv','x-ua-compatible')
	e.setAttribute('content','ie=8')
	if(document.IHTMLDocument2_write){
		document.IHTMLDocument2_write(e.outerHTML)
	} else {
		document.write(e.outerHTML)
	}
	return document
};
// Формирование документа в режиме максимальной версии
var document = createHTMLDocument('Edge');
// Получение ссылки на родительский объект окна
var window = document.parentWindow;
// Получение ссылки на JSON объект
var JSON = window.JSON;

// Создание функции, которая будет делать обёртку на NET функцию
window.execScript('function createReviverWrap(fn){return function(key,value){return fn(key,value)}}')
	
try {
	// Подготовка данных
var v=0;	
	//var data = responsedata; 
       var data = '[{"title":"Конференция","date":"2014-11-30T12:00:00.000Z"},{"title":"Заседание","date":"2014-11-30T16:00:00.000Z"}]';
       System.Console.Write(data); //var wrs =""	
	// Разбор данных
	var object = JSON.parse(data,window.createReviverWrap(function(key,value){
		//Console.WriteLine(key + ': ' + value)
	key.replace(/^\s+|\s+$/g, ''); //
        if (~key.indexOf("name")) {                  
        } else {
        //arrayList.Add(value); //34
        //_JScriptArray.push(key);
        Console.WriteLine(key + ' ' +value + ' '+ v);
        v++;
	}
	return value
	}))   	
	//Console.WriteLine('--------------------') 	
	// Сборка объекта в текстовое представление и вывод результата
	Console.WriteLine(JSON.stringify(object,,'\t'))  	
} catch(e){
	Console.WriteLine('JSON parse error. ' + e);
}

}
}
}

saveJson.Main(Environment.GetCommandLineArgs());

53

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

NovaRo, вернулся с дачи. Решил заглянуть как у Вас прогресс. ) О боги... Ну прекращайте уже мучать COM объект. Ещё раз повторяю - это неверный путь. Тупиковый. Неудачно выбранный. Вы же уже убедились, что с JSON.NET всё работает. ) Используйте его.

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