Я немного увлекаюсь веб-программированием в свободное время. Было решено написать свой велосипед, и, заодно совместить приятное с полезным. Была изучена возможность с помощью консоли управлять компьютером, в первую очередь меня интересовал следующий минимальный объем задач (который немного увеличился в последствии):
- Возможность отправить ПК в режим сна
- Возможность выключить громкость
С помощью известного поисковика нашел консольную программу, 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.
Комментарии (41)
r1zar
08.08.2016 13:38Тоже писал для себя нечто подобное, было еще управление мышкой, возможность передачи нажатия любой клавиши и авторизация по Basic Auth.
Добавляет много комфорта, но я не доверяю сам себе в плане безопасности, поэтому перестал пользоваться. Лучше уж встать и нажать на кнопки, чем увеличивать риск предоставить полное управление злоумышленнику.
HunterXXI
08.08.2016 13:45Отлично. Можно добавить авторизацию по токенам или сертификатам и любой мобильный девайс станет пультом управления для того устройства где установлен даный скрипт. В некоторых ситуация может быть весьма удобно.
Sad_Bro
08.08.2016 13:53буду благодарен если покритикуете мое ООП, буквально первые шаги делаю.
saksmt
09.08.2016 00:36ООП тут нет, почти совсем.
Да и не настолько это большое приложение, чтоб об этом думать.(Естественно об этом надо задумываться, но иногда имеет смысл сделать проще) Как домашняя поделка для себя вполне сойдёт, но пожалуй было ошибкой выкладывать это сюда, впрочем как и на гитхаб. Если хотите попрактиковаться в PHP — выберите задачу посложнее (или эту преобразуйте), почитайте PSR, постигните composer, напишите свой велосипедофреймворк (главное не забудьте его потом выкинуть) и возьмите что-нибудь достойное — symfony, zend, phalcon,… Ну и хабру на эту тему почитайте уже сотни одних и тех же рекомендаций написано.
Ну и добро пожаловать на хабр!
Sad_Bro
09.08.2016 09:11Спасибо! буду ковырять дальше. PSR не уделял внимания совершенно, оставил «на потом», на что сразу обратили внимание на гитхаб) в общем начинаю вникать)
vanxant
15.08.2016 01:14Вот несогласен с saksmt, не стоит сразу грузиться монстрами типа zend-а или симфони. Пока доберётесь до уровня, где они нужны — модны будут совсем другие фреймворки.
Писать свой велосипед с нуля сейчас тоже неактуально, сначала нужно посмотреть, «чё там как у других».
Начните с чего-нибудь лёгкого, но прекрасного. Типа peej/tonic. Попробуйте переписать свой проект под него. Мозги сразу вправятся в нужную сторону, при этом не засоряясь мусором.Sad_Bro
15.08.2016 09:28у меня план сейчас такой,- уяснить принципы популярных паттернов, остановится на наиболее востребованом (на сегодня я так понял это MVC), далее планирую погрузится в Yii, пока остановился на нем, просто из за того что информация по нему вроде как достаточно.
saksmt
16.08.2016 20:26Без своих велосипедов далеко не уедешь, ну это ИМХО конечно. Сам ровно так учился к простому (silex) я пришёл в итоге своей php-карьеры, после чего радостно нырнул в яву.
- Я не говорил, что велосипед должен быть гигантским, что-нибудь простенькое для понимания фабрик, фронт-контроллера и т.д.
mihmig
08.08.2016 14:10-1>>запрос текущего уровня громкости
Поверхностный поиск не дал результатов, придётся писать маленькую консольную утилитку на Delphi
А вообще, если канал связи позволяет — поставьте teamViewer — полный доступ к компьютеру со смартфона.Psychosynthesis
08.08.2016 16:19А это не всегда удобно. У меня например 4'' смарт (принципы, знаете ли), в мелкие элементы с него тыкать крайне неудобно.
Да и как-то запускать tV чтобы трек переключить, ну… кхм…
Tallanvor
08.08.2016 14:20С одной стороны, это ценно само по себе именно с точки зрения «сделать самому».
Но с другой, «всё уже придумано до нас» — MaxRemote имеет весь необходимый функционал.
vconst
08.08.2016 14:37Не хочу критиковать проект автора, но у меня все функции выполняет из коробки — радиоклавиатура от логитек. Макмини с убунтой воткнут в телек и используется как торрето-качалка-смотрелка, радиомышка и радиоклава валяются на тумбочке у дивана и телефон для управления компом совершенно не нужен
Sad_Bro
08.08.2016 16:00Спасибо, за критику, не могу минуса подправить к сожалению, так как уровень не тот. Да конечно я знал про teamViewer, но столь мощный комбайн мне был не нужен, как я писал цель была свой простой велосипед придумать, что и было сделано в каком то объеме.
Andrusha
08.08.2016 18:51Ну TeamViewer тут действительно избыточен, есть специально заточенные программы для превращения смартфона в пульт управления. Например, Unified Remote
ionicman
08.08.2016 19:15Не, круто конечно… но why is so complicated?
Цена вопроса — 300 рублей (даже меньше) + возможность управлять мышкой с пульта, причем вполне себе полноценно.
Если не хватает того, что идет из коробки (что мало вероятно, но может быть — биндинг нужных scan-кодов на нужные ф-ии)
HunterXXI
08.08.2016 23:21ты не чуешь перспективу. управлять то можно через интернет. например выключить удаленно или включить. например грабителя так можно напугать…
ionicman
09.08.2016 12:30Не, перспективу я не чую, я чую задачу автора, которую он четко описал :)
Задача была — управлять с дивана базовыми функциями проигрывания аля громкость / пуск / пауза и т.д. + сервисное типа «выключить комп». С этим данный девайс справляется на ура без велосипедов и строчек кода. Цена вопроса — 300 рублей :D
А управлять через интернет можно элементарно — OpenVPN на роутер, wakeup-lan на комп и ammyadmin (teamviewer) в автозагрузку (если винда), а если нет — обычный SSH и все.
А дальше телефон / планшет с OpenVPN + программой удаленки.
ExplosiveZ
08.08.2016 23:12Отличная идея! Изучаю JavaEE, попробую реализовать такое.
Те, кто предлагают поставить TeamViewer/radmin/rdp/%app_name% — вы серьёзно? Загружать машину непонятным софтом, который требует много ресурсов(относительно данной реализации).
А тем, кто говорит, что можно купить мышь/клавиатуру/%device_name% — товарищ реализовал это скорее всего за пол часа перерыва и эта вещь имеет куда больший потенциал, чем %device_name% с 1,5 функциями.akaSStalkALEX
09.08.2016 10:42Стоит TeamViewer много лет, весьма понятный софт и, скорее всего, требует столько же ресурсов, сколько веб-сервер, может меньше.
instalator
09.08.2016 09:07В умном доме понадобилось управлять компьютером, написал себе такую программку, пользуюсь полгода, замечаний нет.
Sad_Bro
09.08.2016 09:12интересный проект!
instalator
09.08.2016 09:19Спасибо! Если интересно, есть несколько статей на https://geektimes.ru/users/instalator/topics/
kalobyte
09.08.2016 09:07+1надо было на шарпе такое делать
вот для образца http://www.sources.ru/csharp/SimpleHttpServer.html
95% можно сделать при помощи powershell, надо только подцепить его к вебсерверу как цги модуль
Ivan_83
09.08.2016 10:22Хабр не торт: всего один человек в теме как надо чтобы было удобно.
ИК приёмник покупается или паяется простейшая схема для подключения к ком порту.
Далее LIRC (WinLIRC под венду) и/или Girder.
Потом некоторое время+усилия чтобы обучить софт реакции на любые любимые пульты ДУ и софт принимать команды.
Я так себе сделал году в 2004 и года до 2009 оно у меня использовалось, потом был переезд, смена юзкейсов… а потом был куплен ящег для семейных просмотров. Сейчас подумываю про внешний мозг к ящику, и хочу чтобы рулился по HDMI-CEC родным пультом.
У меня была рулёжка:
— громкостью
— винампом: вкл/выкл, пауза, плей, далее, прев.
— виндовс медиа плеером: плей/пауза
— вкл/выкл красивые опенгл часики на весь экран
— блокировка (Win+L)
— Кажется ещё было переключение каналов в софтине от тв тюнера(бехолдер), и соответственно её запуск/сворачивание в трей.
К вопросу юзабилити: обычный пду в 100500 раз удобнее всяких планшетов, фуфлонов и прочего барахла с сенсорным экраном потому что:
— стоит копейки / или вообще бесплатно от помершей техники
— не нужно смотреть куда жмёшь, крайне легко на ощупь ориентироваться — это весьма актуально
— зарядка батарейками раз в пару лет
И удобнее всяких дистанционных клав/мышек, по тем же причинам. Плюс для пду не требуется орлиное зрение дабы разглядеть курсор через всю комнату.
2 Sad_Bro
Хочешь критики — участвуй в чужих опенсорсных проектах.instalator
09.08.2016 10:39Задачи удаленного управления бывают разные. IR хорошо, но что делать если комп в другом помещении? Я делал управление для автоматизации, например сценарий Музыка, включается кмоп (если выключен) запускается foobar (люблю я его, слушаю lossles), ресивер переключается на вход PC и начинает играть музыка, не прикасаясь к пульту. сценарии запускаю голосовыми командами.
Notimer
09.08.2016 10:42+1Или включить MediaPlayer Classic, у которого уже из коробки веб-морда, слушающая нужный порт (по дефолту отключен)
nikitasius
ssh, не?
HunterXXI
причем здесь ssh? Разве заголовок статьи звучит «Я нифига не понял как управлять компьютером удаленно и поэтому сделал все на PHP». Помоему нет.
nikitasius
К тому, что если есть доступ на комп, то можно поставить на андроид простой ssh клиент и спокойно рулит компом, закинув пару bash скриптов, если что-то по памяти не помнишь, а не городить на php со всеми вытекающими.
Andrusha
Эээ… Вы предлагаете каждый раз на экранной клавиатуре набирать команды вместо того чтобы по одной кнопке для каждой команды тапать? По-моему, вышеописанный огород эргономичнее будет.
nikitasius
Тапнуть ./ это тоже быстро.
Taragolis
Судя по скриптам все это из под Windows крутится
nikitasius
Я то вижу. Было бы решение кросплатформенным, было бы хорошо.
Taragolis
Не думаю, что для такой задачи тянуть OpenSSH в Windows хорошая идея. Да и кроссплатформенным это решения навряд ли будет
akdes
Статья о контроле компа браузером…
Решение имеет место быть… Если бы автор захотел контролить ssh, он бы написал «Управление компьютером с помощью ssh»