Компьютер давно многим заменил телевизор, а что не хватает компьютеру для комфортного просмотра кино, сериалов и прочего? Мне, лично, не хватало пульта дистанционного управления.

Я немного увлекаюсь веб-программированием в свободное время. Было решено написать свой велосипед, и, заодно совместить приятное с полезным. Была изучена возможность с помощью консоли управлять компьютером, в первую очередь меня интересовал следующий минимальный объем задач (который немного увеличился в последствии):
С помощью известного поисковика нашел консольную программу, NirCmd, программа позволяет осуществлять достаточно много действий кроме указанных выше. С основной частью мы определились. Как я говорил, немного изучаю php, веб-сервер у меня как правило запущен постоянно, поэтому ничего специфичного в плане сервера я придумывать не стал. Сервер написан на php и состоит из двух классов: Control, который представляет собой методы, которые исполняют консольные команды и Route, который делает валидацию приходящих запросов и исполняет методы класса Control.
Control выгладит вот так (код однотипный, поэтому я сократил):
Второй класс, — Route. Собственно, к нему обращается клиент. Класс, в первую очередь осуществляет валидацию запроса, и, если запрос правильный вызывает методы класса Control.
Выглядит это так:
Чтобы получилось в случае чего легко расширить количество методов в классе Control, валидация в классе Route жестко не привязана к определенному списку методов класса Control, точнее привязана, но все возможные методы извлекаются из самого объекта, с ними и идет сравнение пришедших данных.
Сам файл к которому обращается клиент выглядит вот так:
Если приходит GET запрос, то весь массив отдаем методу route.
Клиентская часть представляет собой кнопки управления и один обработчик, по которому мы шлем данные при помощи ajax на сервер.
На сегодня реализован следующий функционал управления:
Все, что я хотел получить, получил, но, как говорится, аппетит приходит во время еды. Хотелось бы иметь обратную связь от сервера, т.е. при первом заходе на страницу делать запрос текущего уровня громкости, например. К сожалению, nirCmd не возвращает значения при выполнении, поэтому с тем, что имеем сейчас, я не знаю, как это осуществить.
Вопрос безопасности. Хотя это все и крутится на локальной машине, будет очень печально, если доступ к исполнению команд nirCmd будет у злоумышленника, т.к. можно сотворить много деструктивных действий.
Готовый проект на GIthub.

Я немного увлекаюсь веб-программированием в свободное время. Было решено написать свой велосипед, и, заодно совместить приятное с полезным. Была изучена возможность с помощью консоли управлять компьютером, в первую очередь меня интересовал следующий минимальный объем задач (который немного увеличился в последствии):
- Возможность отправить ПК в режим сна
- Возможность выключить громкость
С помощью известного поисковика нашел консольную программу, NirCmd, программа позволяет осуществлять достаточно много действий кроме указанных выше. С основной частью мы определились. Как я говорил, немного изучаю php, веб-сервер у меня как правило запущен постоянно, поэтому ничего специфичного в плане сервера я придумывать не стал. Сервер написан на php и состоит из двух классов: Control, который представляет собой методы, которые исполняют консольные команды и Route, который делает валидацию приходящих запросов и исполняет методы класса Control.
Control выгладит вот так (код однотипный, поэтому я сократил):
class Control implements ActionControl { protected $Path; //путь до программы nirCmd; function __construct($p = 'C:/nircmd/nircmd.exe') { $this->Path = $p; } function standby() { `{$this->Path} standby`; } function hibernate() { `rundll32 powrprof.dll,SetSuspendState 0,1,0`; } function reboot() { `{$this->Path} exitwin reboot`; } function turnOff() { `{$this->Path} exitwin poweroff`; } function logout() { `{$this->Path} exitwin logoff`; } }
Второй класс, — Route. Собственно, к нему обращается клиент. Класс, в первую очередь осуществляет валидацию запроса, и, если запрос правильный вызывает методы класса Control.
Выглядит это так:
class Route implements ActionRoute { protected $possible = []; protected $ControlObj; function __construct($obj) { $this->possible = get_class_methods($obj); $this->ControlObj = $obj; } function route($arr) { forEach($arr as $key => $value) { if (in_array($key, $this->possible) && $value == 'true') { $this->execute($key); } else { Message::sent('wrong method'); } } } function execute($c) { $this->ControlObj->$c(); Message::sent('executed'); } }
Чтобы получилось в случае чего легко расширить количество методов в классе Control, валидация в классе Route жестко не привязана к определенному списку методов класса Control, точнее привязана, но все возможные методы извлекаются из самого объекта, с ними и идет сравнение пришедших данных.
Сам файл к которому обращается клиент выглядит вот так:
<? define("PATH", "C:/nircmd/nircmd.exe"); function __autoload($name) { require "class/$name.class.php"; } $obj = new Control(PATH); $route = new Route($obj); if ($_GET) { $route->route($_GET); } ?>
Если приходит GET запрос, то весь массив отдаем методу route.
Клиентская часть представляет собой кнопки управления и один обработчик, по которому мы шлем данные при помощи ajax на сервер.
var wrapper = document.querySelector(".wrapper"); function getXmlHttpRequest(){ if (window.XMLHttpRequest) { try { return new XMLHttpRequest(); } catch (e){ } } else if (window.ActiveXObject) { try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch (e){} try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e){} } return null; } wrapper.addEventListener('click', function(e){ var target = e.target; if(target.tagName!= 'BUTTON') return; if (target.getAttribute('data')=='qestion') { var yn = confirm("Уверен?"); if (!yn) return ajaxf(target.id); } ajaxf(target.id); }) function ajaxf($com) { var command = $com+'=true'; var xhr = new getXmlHttpRequest(); xhr.open('GET', 'remote.php?'+command, true); xhr.send(); xhr.onreadystatechange = function() { if (xhr.readyState != 4) return; if (xhr.status != 200) { console.log(xhr.status + ': ' + xhr.statusText); } else { console.log(xhr.responseText); } } }
На сегодня реализован следующий функционал управления:
- спящий режим
- гибернация
- перезагрузится
- выключить
- выйти
- выключить монитор
- включить/отключить звук по триггеру
- громкость больше
- громкость меньше
- Медиа кнопки, stop/play next/prev
Все, что я хотел получить, получил, но, как говорится, аппетит приходит во время еды. Хотелось бы иметь обратную связь от сервера, т.е. при первом заходе на страницу делать запрос текущего уровня громкости, например. К сожалению, nirCmd не возвращает значения при выполнении, поэтому с тем, что имеем сейчас, я не знаю, как это осуществить.
Вопрос безопасности. Хотя это все и крутится на локальной машине, будет очень печально, если доступ к исполнению команд nirCmd будет у злоумышленника, т.к. можно сотворить много деструктивных действий.
Готовый проект на GIthub.
