Как стать автором
Обновить

Комментарии 32

Ну раз тема называется «Удаленное включение по Mac-адресу C# (Wake On Lan)», а не что-то вроде «код моей программы для включения ПК», то, полагаю, Вы достаточно хорошо разобрались и в самой теме «Wake On Lan».
В связи с этим просьба подсказать мне,
1) компьютер может быть именно выключен, или же должен находится в спящем режиме?
2) каким образом организовать включение ПК через интернет, а точнее через роутер, при условии, что роутер не поддерживает специальных функций для «Wake On Lan». Т.е. на примере бюджетных роутеров.
В связи с этим могу предложить более надежный способ.

— Дорогая, ты дома?
— Да…
— Супер! Жмякни кнопку на системнике, плииииз.
— А моник включать? Неее… не нужно. Спасибки, целую, до вечера!
Проблема кроется во второй строчке диалога :)
ХеХе Тогда уж начнем с проблемы наличия жены…

Да, согласен, есть такой шанс, что не будет дома человека. Но также может произойти сбой в электросети, из-за чего ПК будет в состоянии, не способном обработать WoL.
Вот ежели реализовать некий аппаратный включатель с подключением к сети… например на МК с модулем WiFi <=> UART. Теоретически можно будет на МК заслать команду включения (текст, известный только хозяйствующему параноику, если угодно).
Возможный вариант: некое веб-приложение, опрашиваемое микроконтроллером с некоей периодичностью (скажем, раз в 10 сек. или минуту).
Может интересно будет решение «Без жены».
habrahabr.ru/post/249507
эту программу я написал живя в общежитии университета, так что я преследовал идею по включению в первую очередь чужих компов удаленно.
Я решил вторую проблему довольно просто, помимо компа дома еще в сети есть Raspberry Pi в которой висит в кроне скрипт с пингом компьютера который должен быть всегда включен и если он не отзывается то посылает магический патетик. Причем добавлено еще и ограничение на количество попыток, а то мало ли с компом чего не так и тогда мне шлется письмо на электронку.
Зачем это? если можно просто не выключать ПК и в биосе указать Restore on AC Power Loss: Last State / Power On?
Лично для меня это исключительно для развлекательной цели, чтобы пошутить над жителями общежития ночью, к примеру.
Но для многих эта статья, я надеюсь, послужит неплохим уроком, и я считаю что статья доволе интересная, другое дело что я преподнес ее для вас так, как считаю я нужным.
Это мое субъективное мнение!
К статье претензий нет. у меня вопрос к Mu57Di3, зачем прикручивать Raspberry, пинговалку и т.п?
Малинка выполняет еще много разных функций, а так как она все равно болтается в сети вот не нее и повесил еще и эту функцию.
Несмешные шутки какие-то у вас в общежитии
Я был огорчен но в биосе материнской платы нет этой функции.
Купил себе Mikrotik, поставил, проблем не ощущаю. Будит всё что надо без напрягов, ну и когда надо.
НЛО прилетело и опубликовало эту надпись здесь
1. Выключен.
2. С совсем дешевыми роутерами, полагаю, никак. Если на роутер есть ssh, то тогда в дело вступает скрипт на перле, который отлично вэйкапит компы.
[zanuda_on] XAML — это разметка. Все равно, что при итальянце обозвать спагетти рожками, например. [/zanuda_on]
Замечания к разметке и архитектуре в целом.
Я понимаю так, что данная реализация скорее всего драфтовый набросок или «proof-of-concept». Но даже для таких целей советую:
  • Избавляться от лени и давать элементам интерфейса осмысленные имена (вместо button2 — StartScanButton — или Buttons_StartScan). Последняя конвенция наименования мне не нравится, т.е. идет в разрез с C# Naming Convention, но в разметке некоторым коллегам нравится такой тэггинг и группировка.
  • Имя элемента задавать через x:Name (в некоторых случаях просто Name некорректно обрабатывается). Ну и располагать x:Name сразу после тэка элемента на той же строке. Тогда если вы схлопните тэг в разметке — вы все равно будете видеть имя.
  • Вместо обработчика событий в Code Behind, все таки реализовать MVVM + ICommand.


Замечания к коду:
label3.Content = ip.ToString();
ipToString = ip.ToString().Split('.');

Два раза один и тот же код вызывается. Можно можно закэшировать строку и Split() вызвать на кэше (локальной переменной).


        string[] ipadressText;
        string[] hostnameText;
        string[] macaddressText;


Не по конвенции C# приватные поля названы. И располагаться они должны в верху. Также с конвенцией наименования есть нарушения и в других местах. Напр., «private void WakeFunction(string MAC_ADDRESS)» (имя параметра).

private void ADd()

Опечатка в имени?

Если бы вы использовали MVVM, то вам не пришлось бы врукопашную очищать и устанавливать в новое значение ItemsSource, а также вызывать явно Items.Refresh().

StreamWriter write = new StreamWriter(@"C:\Users\***\IPMAC.txt", true);

            for (int index = 0; index < _host.Count; index++)
            {

                if (!macaddressText.Contains(_host[index].MacAdress))
                    write.WriteLine(_host[index].ipAdress + "#" + _host[index].nameComputer + "#" + _host[index].MacAdress);
            }
            write.Close();

Лучше так:

using(var write = new StreamWriter(@"C:\Users\***\IPMAC.txt", true))
{
    // writer usage goes here
    // no need to call Close explicitly
}
Да, можно было сделать намного получше, но я не преследовал цель создать что то идеальное и уникальное, а по сути просто постарался объединить два вопроса в один, надеясь на то, что кому нибудь моя статья поможет в решение какой либо проблемы.
Когда публикуете код, особенно если это на Хабре, имейте в виду, что велик шанс, что никто не догадается, что в мыслях у вас была установка, что код этот очень-очень черновой. Скопипастят новички и будут тиражировать дальше.
Но с другой стороны, при излишествах в виде полноценного MVVM (с разнесением каждого из слоев по разным проектам) потеряется суть описываемого подхода и фокус сместится. Тем же новичкам будет тяжело понять и они «забьют».
Не обязательно разносить по слоям на сборки. Подкаталоги в проекте как раз удовлетворяют драфтовости приложения и не нарушают требования культуры.
Как только свыкаетесь с MVVM, написание кода становится не намного более медленным. На автомате все пишется. Если еще подключите сборки Expression Blend Interaction, то и ICommand станут не нужны. Можно будет из XAML вызывать публичные методы в ViewModel.

Кроме того, отделив логику от UI, Вы еще больше сконцентрируете внимание читателя чисто на логике.
Я-то как раз предпочитаю в рабочих проектах следовать практике этого паттерна. Но в тестовых проектах, обучающих примерах чаще всего не использую.

Если еще подключите сборки Expression Blend Interaction

Мне не нравится та монструозность в разметке, которую привносит Interaction. Я настолько полюбил Caliburn.Micro, что от Interaction-ов в xaml впадаю в депрессию ))
Спасибо вам за комментарий. По-моему, вот так, с разбором ошибок, даже полезней получается, чем изначально был бы «православный» код :)

ps
А ещё там во втором листинге ipAdress без одной буквы =(
Не допускаю :0) Ну вот когда intellisense и всё такое, то почти пофиг, но бывают специфические ситуации, когда волею судьбы на С и в убогом редакторе без автодополнения достаётся чужой код, где сплошь вот такие «adress» и прочие «devise» — это, скажем, не делает мир лучше, а сопровождение — проще. Вы даже опечатку в имени метода SetClientToBroadcastMode перенесли к себе. CodeNazi негодуэ ;D
Это не CodeNazi, и не только культура программирования.
1. Naming Convention нужна, чтоб ускорить понимание кода.
2. Орфография и грамматика английского в C# также важна для понимания того, что делает метод например. Писать комментарии может быть долше, чем адекватное название для метода, например.

Вот например для инстанциирования ICommand может потребоваться реализовать метод выдающий bool (активация и деактивация команды). Как его назвать? Параметры конструктора обзываются: execute и canExecute.

Назовете методы именами вида: BlaBlaCommandExecute и BlaBlaCommandCanExecute
и другому члену команды секунды хватит взгляда на эти имена, чтобы понять их предназначение.

А назовете их например так: HandlerOfBlaBlaCommand и IsBlaBlaCommandEnabled
сразу вопросы появляются. Последний метод по форме названия на свойство больше похож. А первый метод на делегат смахивает. Тут что имеет место подписка на событие? А что там с утечками?

Кроме того, если оба метода начинаются одинаково, то они в навигаторе по методам группируются.
BlaBlaCommand (get; set)
BlaBlaCommandExecute
BlaBlaCommandCanExecute

Потому я счтаю граматически привильное наименование очень важным при коммандной разработке.
Кстати, на практике все же приходится в Code Behind уходить для реализации некоего специфичного поведения (спасибо UX спецам). Но для этого удобно Expression Blend Behavior<...> использовать.
Dependency и Attached Properties именно для этого и придуманы ;-) Behaviors да, очень мощный и полезный механизм.
У AttachedProperty очень сложный жизненный цикл. Разработчику в статическом сеттере необходимо создавать инстанс текужего же класса, приаттачивать его еще одним статическим сеттером к контролу и забывать референс на только что созданный инстанс, либо класть его в статическое поле. Если к этому прибавляется еще и подписка на событие, то часто используется статически определенный делегат (привет утечки).
А Behavior<..> прост в этом отношении. Точка входа — OnAttached(...). Работаешь только с конкретными инстансами носителя и самого Behavior. Опять же в Behavior Вы вольны пользоваться хоть DP, хоть обычными свойствами. Единственный недостаток Behavior, что его нельзя в явном виде прицепить в сеттере стилей, например.
Статью можно было вполне ограничить кодом методов WakeFunction и GetInform, реализовав их в виде мини-библиотеки. Всё остальное, включая разметку и codebehind — смысловой нагрузки по теме статьи не несет, поэтому лучше это выложить на Github.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации