Для начала скачаем бинарник websocketd.
Пишем код:
WScript.Echo(WScript.StdIn.ReadLine());
Сохраним файл с именем console1.js.
Пишем еще один не менее сложный код:
@echo off cscript /nologo console1.js
Сохраняем с именем console.cmd.
Итак, все три файла у нас находятся в одном каталоге: websocketd.exe, console.cmd, console1.js.
Открываем консоль, запускаем демона:
websocketd --port 8081 console.cmd
Пишем код клиента:
<!DOCTYPE html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <textarea id="txt" cols="60" rows="10"></textarea><br/> <input id="btn" type="button" value="R U N"/> <pre id="log"></pre> <script> btn.addEventListener('click', function(e) { var ws = new WebSocket('ws://localhost:8081/'); ws.onopen = function() { log('CONNECTED'); ws.send(txt.value); }; ws.onmessage = function(e) { log('MESSAGE: ' + e.data); }; ws.onclose = function(e) { log('DISCONNECTED: code = ' + e.code); }; }); function log(msg) { document.getElementById('log').innerText += msg + '\n'; } </script>
Сохраняем файл с расширением html, открываем в браузере, отправляем серверу приветствие, получаем ответ:
Такой эхо-сервер получился.
Дальше - интереснее. На счет 15 минут я точно поторопился. И вот спустя пару часов я могу рассказать, как собрать заявленный в заголовке велосипед за 15 минут :).
Веб-интерфейс велосипеда, который я назвал WS-console, выглядит следующим образом:
Просто, без изысков.
Исходный код клиентской части:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>WS-console</title> </head> <body> IP: <input id="ip" type="text" value="127.0.0.1"> Port: <input id="port" type="text" value="8081"><br/> <textarea id="txt" cols="60" rows="10"></textarea><br/> <input id="btn" type="button" value="R U N"/> <input id="vbs" type="radio" name="code" checked> VBScript <input id="js" type="radio" name="code"> JScript <pre id="log"></pre> <script> document.getElementById('txt').focus(); btn.addEventListener('click', function(e) { var ip = document.getElementById('ip').value, port = document.getElementById('port').value, ws = new WebSocket('ws://' + ip + ':' + port); ws.onopen = function() { log('CONNECTED'); var d = document.all ? '\r\n' : '\n'; var arr = txt.value.split(d); var js = document.getElementById('js'), msg; if (js.checked) { for (var i=0; i<arr.length; i++) { arr[i] = arr[i].replace(/(\/\*([\s\S]*?)\*\/)|(\/\/(.*)$)/g, ''); } msg = arr.join(' '); } else { var und = false; for (var i=0; i<arr.length; i++) { if (arr[i].search(/ _$/) != -1) { arr[i] = arr[i].replace(/ _$/, ''); arr[i] += arr[i+1]; arr.splice(i+1, 1); i--; continue; } arr[i] = arr[i].replace(/^\s+|^\s*(?:'|\brem\b).*$|(?:'|\brem\b)[^(?:\"|_$)].*$|\s+$/gi, ''); } msg = arr.join(' : '); } ws.send(msg); }; ws.onmessage = function(e) { log('MESSAGE: ' + e.data); }; ws.onclose = function(e) { log('DISCONNECTED'); log('Clean = ' + e.wasClean + ', Code = ' + e.code + ', Reason = ' + (e.reason || 'none')); }; }); function log(msg) { document.getElementById('log').innerText += msg + '\n'; } </script> </body> </html>
Здесь у меня возникли трудности с нижним подчеркиванием, которое используется в VBScript для переноса кода на новую строку. Пришлось писать дополнительный код на JavaScript, чтобы просечь этот момент. Регулярное выражение для удаления комментариев у меня уже было: VBShaker - мое творение :).
Код, на котором я тестировал, выглядит так:
- VBScript:
Set wshNetwork = WScript.CreateObject( "WScript.Network" ) For i=0 To 4 'тестовый цикл j = j & i Next WScript.Echo("ComputerName: " & wshNetwork.ComputerName & vbCrLf _ & "UserName: " & wshNetwork.UserName & vbCrLf & "j = " & j)
-JScript:
var wshNetwork = new ActiveXObject( 'WScript.Network' ); var j = ''; for (var i=0; i<5; i++) { // тестовый цикл j = j + i; } WScript.Echo('ComputerName: ' + wshNetwork.ComputerName + '\nUserName: ' + wshNetwork.UserName + '\nj = ' + j);
Выполнение любого из приведенных кодов (русский не родной :), главное понятно) дает нам такой результат:
Приступаем к тестированию.
Начнем с VBScript. Пишем код файла console.vbs:
Call Execute(WScript.StdIn.ReadLine())
Метод Execute выполнит все, что прилетит к нему в стандартном входном потоке.
Редактируем код файла console.cmd:
@echo off cscript /nologo console.vbs
Запускаем websocketd (если еще не запущен), открываем нашу консоль WS-console, выполняем код VBScript:
Все OK. Переходим к JScript. Пишем код файла console.js:
eval(WScript.StdIn.ReadLine());
Не менее трудный для понимания код :). По аналогии с VBScript в JScript мы используем метод eval().
Редактируем код файла console.cmd:
@echo off cscript /nologo console.js
Копируем в нашу консоль код JScript, выполняем:
Все в елочку.
В завершение.
Для того, чтобы выполнить код на удаленной машине необходимо доставить на нее файлы websocketd.exe, console.cmd и console.js (или console.vbs), а также запустить демона websocketd. Как это сделать - не моя забота - есть варианты.
Вероятно придется открыть соответствующий порт. Я тестировал на локальной машине и при первом запуске websocketd мой межсетевой экран ругался.
Если в процессе тестирования кода у вас возникнут ошибки, дайте мне знать, и я постараюсь их исправить.
Я привел самый простой пример удаленного выполнения кода, без авторизации, шифрования и пр. плюшек, реализацию которых оставляю на откуп любознательному читателю, осилившему этот пост до самого конца :).
UPD: На следующий день я создал репозиторий на GitHub, сделал pull request, автор websocketd заценил и добавил ссылку на созданный проект в раздел Example Project. Happy End :).
Комментариев нет:
Отправить комментарий
Комментарий будет опубликован после модерации