Тема: 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\
"
}