Управляем компьютером через браузер

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

image

Я немного увлекаюсь веб-программированием в свободное время. Было решено написать свой велосипед, и, заодно совместить приятное с полезным. Была изучена возможность с помощью консоли управлять компьютером, в первую очередь меня интересовал следующий минимальный объем задач (который немного увеличился в последствии):

  • Возможность отправить ПК в режим сна
  • Возможность выключить громкость

С помощью известного поисковика нашел консольную программу, 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.
Share post

Comments 41

    –3
    ssh, не?
      +3
      причем здесь ssh? Разве заголовок статьи звучит «Я нифига не понял как управлять компьютером удаленно и поэтому сделал все на PHP». Помоему нет.

        0
        К тому, что если есть доступ на комп, то можно поставить на андроид простой ssh клиент и спокойно рулит компом, закинув пару bash скриптов, если что-то по памяти не помнишь, а не городить на php со всеми вытекающими.
          +1
          Эээ… Вы предлагаете каждый раз на экранной клавиатуре набирать команды вместо того чтобы по одной кнопке для каждой команды тапать? По-моему, вышеописанный огород эргономичнее будет.
            0
            Тапнуть ./ это тоже быстро.
            +1
            Судя по скриптам все это из под Windows крутится
              0
              Я то вижу. Было бы решение кросплатформенным, было бы хорошо.
                0
                Не думаю, что для такой задачи тянуть OpenSSH в Windows хорошая идея. Да и кроссплатформенным это решения навряд ли будет
          +1
          Статья о контроле компа браузером…
          Решение имеет место быть… Если бы автор захотел контролить ssh, он бы написал «Управление компьютером с помощью ssh»
          0

          Тоже писал для себя нечто подобное, было еще управление мышкой, возможность передачи нажатия любой клавиши и авторизация по Basic Auth.
          Добавляет много комфорта, но я не доверяю сам себе в плане безопасности, поэтому перестал пользоваться. Лучше уж встать и нажать на кнопки, чем увеличивать риск предоставить полное управление злоумышленнику.

            –2
            Готовый проект на GIthab.

            Вообще-то, GitHub.
              0
              да, конечно, подправил
              0
              Отлично. Можно добавить авторизацию по токенам или сертификатам и любой мобильный девайс станет пультом управления для того устройства где установлен даный скрипт. В некоторых ситуация может быть весьма удобно.
                0
                Спасибо. Если выпускать в интернет только, но с таким функционалом смысла нет. А так да, думал сделать для «потренироваться».
                  0
                  из лиги лени, приятно включив фильм и раскинувшись на диване, через телефон увеличивать громкость. Почему нет? =)
                0
                буду благодарен если покритикуете мое ООП, буквально первые шаги делаю.
                  0

                  ООП тут нет, почти совсем. Да и не настолько это большое приложение, чтоб об этом думать. (Естественно об этом надо задумываться, но иногда имеет смысл сделать проще) Как домашняя поделка для себя вполне сойдёт, но пожалуй было ошибкой выкладывать это сюда, впрочем как и на гитхаб. Если хотите попрактиковаться в PHP — выберите задачу посложнее (или эту преобразуйте), почитайте PSR, постигните composer, напишите свой велосипедофреймворк (главное не забудьте его потом выкинуть) и возьмите что-нибудь достойное — symfony, zend, phalcon,… Ну и хабру на эту тему почитайте уже сотни одних и тех же рекомендаций написано.


                  Ну и добро пожаловать на хабр!

                    0
                    Спасибо! буду ковырять дальше. PSR не уделял внимания совершенно, оставил «на потом», на что сразу обратили внимание на гитхаб) в общем начинаю вникать)
                      0
                      Вот несогласен с saksmt, не стоит сразу грузиться монстрами типа zend-а или симфони. Пока доберётесь до уровня, где они нужны — модны будут совсем другие фреймворки.
                      Писать свой велосипед с нуля сейчас тоже неактуально, сначала нужно посмотреть, «чё там как у других».
                      Начните с чего-нибудь лёгкого, но прекрасного. Типа peej/tonic. Попробуйте переписать свой проект под него. Мозги сразу вправятся в нужную сторону, при этом не засоряясь мусором.
                        0
                        у меня план сейчас такой,- уяснить принципы популярных паттернов, остановится на наиболее востребованом (на сегодня я так понял это MVC), далее планирую погрузится в Yii, пока остановился на нем, просто из за того что информация по нему вроде как достаточно.
                          0

                          Без своих велосипедов далеко не уедешь, ну это ИМХО конечно. Сам ровно так учился к простому (silex) я пришёл в итоге своей php-карьеры, после чего радостно нырнул в яву.


                          • Я не говорил, что велосипед должен быть гигантским, что-нибудь простенькое для понимания фабрик, фронт-контроллера и т.д.
                    –1
                    >>запрос текущего уровня громкости
                    Поверхностный поиск не дал результатов, придётся писать маленькую консольную утилитку на Delphi

                    А вообще, если канал связи позволяет — поставьте teamViewer — полный доступ к компьютеру со смартфона.
                      0
                      А это не всегда удобно. У меня например 4'' смарт (принципы, знаете ли), в мелкие элементы с него тыкать крайне неудобно.

                      Да и как-то запускать tV чтобы трек переключить, ну… кхм…
                      0
                      С одной стороны, это ценно само по себе именно с точки зрения «сделать самому».
                      Но с другой, «всё уже придумано до нас» — MaxRemote имеет весь необходимый функционал.
                        0
                        Не хочу критиковать проект автора, но у меня все функции выполняет из коробки — радиоклавиатура от логитек. Макмини с убунтой воткнут в телек и используется как торрето-качалка-смотрелка, радиомышка и радиоклава валяются на тумбочке у дивана и телефон для управления компом совершенно не нужен
                          0
                          Спасибо, за критику, не могу минуса подправить к сожалению, так как уровень не тот. Да конечно я знал про teamViewer, но столь мощный комбайн мне был не нужен, как я писал цель была свой простой велосипед придумать, что и было сделано в каком то объеме.
                            0
                            Ну TeamViewer тут действительно избыточен, есть специально заточенные программы для превращения смартфона в пульт управления. Например, Unified Remote
                            0
                            Не, круто конечно… но why is so complicated?
                            Цена вопроса — 300 рублей (даже меньше) + возможность управлять мышкой с пульта, причем вполне себе полноценно.
                            Если не хватает того, что идет из коробки (что мало вероятно, но может быть — биндинг нужных scan-кодов на нужные ф-ии)

                              0
                              ты не чуешь перспективу. управлять то можно через интернет. например выключить удаленно или включить. например грабителя так можно напугать…
                                0
                                Не, перспективу я не чую, я чую задачу автора, которую он четко описал :)
                                Задача была — управлять с дивана базовыми функциями проигрывания аля громкость / пуск / пауза и т.д. + сервисное типа «выключить комп». С этим данный девайс справляется на ура без велосипедов и строчек кода. Цена вопроса — 300 рублей :D

                                А управлять через интернет можно элементарно — OpenVPN на роутер, wakeup-lan на комп и ammyadmin (teamviewer) в автозагрузку (если винда), а если нет — обычный SSH и все.

                                А дальше телефон / планшет с OpenVPN + программой удаленки.
                              0
                              Отличная идея! Изучаю JavaEE, попробую реализовать такое.
                              Те, кто предлагают поставить TeamViewer/radmin/rdp/%app_name% — вы серьёзно? Загружать машину непонятным софтом, который требует много ресурсов(относительно данной реализации).
                              А тем, кто говорит, что можно купить мышь/клавиатуру/%device_name% — товарищ реализовал это скорее всего за пол часа перерыва и эта вещь имеет куда больший потенциал, чем %device_name% с 1,5 функциями.
                                0
                                Стоит TeamViewer много лет, весьма понятный софт и, скорее всего, требует столько же ресурсов, сколько веб-сервер, может меньше.
                                0
                                В умном доме понадобилось управлять компьютером, написал себе такую программку, пользуюсь полгода, замечаний нет.
                                  0
                                  интересный проект!
                                    0
                                    Спасибо! Если интересно, есть несколько статей на https://geektimes.ru/users/instalator/topics/
                                  +1
                                  надо было на шарпе такое делать
                                  вот для образца http://www.sources.ru/csharp/SimpleHttpServer.html

                                  95% можно сделать при помощи powershell, надо только подцепить его к вебсерверу как цги модуль
                                  • UFO just landed and posted this here
                                      0
                                      Задачи удаленного управления бывают разные. IR хорошо, но что делать если комп в другом помещении? Я делал управление для автоматизации, например сценарий Музыка, включается кмоп (если выключен) запускается foobar (люблю я его, слушаю lossles), ресивер переключается на вход PC и начинает играть музыка, не прикасаясь к пульту. сценарии запускаю голосовыми командами.
                                      +1
                                      Или включить MediaPlayer Classic, у которого уже из коробки веб-морда, слушающая нужный порт (по дефолту отключен)
                                        0

                                        Для себя что-то подобное написал используя бота Telegram на Python2.7.

                                          0
                                          Компьютер можно удаленно включать, если использовать WakeOnLan.

                                          Only users with full accounts can post comments. Log in, please.