В этой статье я хотел бы поделиться небольшим опытом удаленного включения компьютера. Эта тема, пожалуй, многим известна, но хотелось бы еще раз уделить внимание данной технологии. Свою статью я разделю на две части:
- Сканирование локальной сети, получение IP-адреса, HostName, Mac-address;
- Создание "magic packet" и отправка.
Вот так примерно выглядит созданная программа:
Итак, приступим к выполнению первого пункта.
1. Сканирование локальной сети: получение IP-адреса, HostName, Mac-address
В настоящее время существует множество программ, которые реализуют данный пункт. В этой статье я напишу пример кода, который будет выполнять поставленную задачу.
Создадим новый проект в Visual Studio WPF C#. Для начала создадим основной элемент- это ListView, где будет выводится полученная информация.
Код XAML
<ListView Margin="12,84,12,12" Name="listView1"> <ListView.ContextMenu> <ContextMenu > <MenuItem Header="Копировать"> <MenuItem Header="IP-adress" Name="copyIP" Click="copyIP_Click" /> <MenuItem Header="HostName" Name="copyName" Click="copyName_Click" /> <MenuItem Header="Mac-adress" Name="copyMacAddress" Click="copyMacAddress_Click" /> </MenuItem> <MenuItem Header="Очистить список" Name="ClearList" Click="ClearList_Click" /> <MenuItem Header="Сохранить список"/> <MenuItem Header="Действия"> <MenuItem Header="Удаленное включение" Name="PowerOn" Click="PowerOn_Click" /> <MenuItem Header="Удаленное завершение" IsEnabled="False" /> </MenuItem> <MenuItem Header="Отмена"/> </ContextMenu> </ListView.ContextMenu> <ListView.View> <GridView> <GridView.Columns> <GridViewColumn Header="IP-Адрес" DisplayMemberBinding="{Binding Path=ipAdress}" Width="200"></GridViewColumn> <GridViewColumn Header="HostName" DisplayMemberBinding="{Binding Path=nameComputer}" Width="250"></GridViewColumn> <GridViewColumn Header="Mac адрес" DisplayMemberBinding="{Binding Path=MacAdress}" Width="250"></GridViewColumn> </GridView.Columns> </GridView> </ListView.View> </ListView>
Код C#
class TableHost { public string ipAdress { get; set; } public string nameComputer { get; set; } public string MacAdress { get; set; } }
Следующим действием узнаем свой IP-адрес и приступим к сканировании локальной сети. Код простой, даже для новичка он не вызовет особых трудностей.
Код C#
// Получение ip-адреса. System.Net.IPAddress ip = System.Net.Dns.GetHostByName(host).AddressList[0]; private void button2_Click(object sender, RoutedEventArgs e) { int i = int.Parse(ipToString[0]); int j = int.Parse(ipToString[1]); { for(int k = 0;k<6;k++) { for (int m = 0; m < 254; m++) { //Запускаем проверку в новом потоке Thread _thread = new Thread(() => GetInform(string.Format("{0}.{1}.{2}.{3}", i.ToString(), j.ToString(), k.ToString(), m.ToString()))); _thread.Start(); } } } } private void GetInform(string textName) { string IP_Address = ""; string HostName = ""; string MacAddress = ""; try { //Проверяем существует ли IP entry = Dns.GetHostEntry(textName); foreach (IPAddress a in entry.AddressList) { IP_Address = a.ToString(); break; } //Получаем HostName HostName = entry.HostName; //Получаем Mac-address IPAddress dst = IPAddress.Parse(textName); byte[] macAddr = new byte[6]; uint macAddrLen = (uint)macAddr.Length; if (SendARP(BitConverter.ToInt32(dst.GetAddressBytes(), 0), 0, macAddr, ref macAddrLen) != 0) throw new InvalidOperationException("SendARP failed."); string[] str = new string[(int)macAddrLen]; for (int i = 0; i < macAddrLen; i++) str[i] = macAddr[i].ToString("x2"); MacAddress = string.Join(":", str); //Далее, если всё успешно, добавляем все данные в список, после чего выводим всё в ListView Dispatcher.Invoke(new Action(() => { _host.Add(new TableHost() { ipAdress = IP_Address, nameComputer = HostName, MacAdress = MacAddress }); listView1.ItemsSource = null; listView1.ItemsSource = _host; })); } catch { } }
Теперь мы имеем всё, что нам необходимо. Приступаем к следующему этапу.
2. Создание «magic packet» и отправка
С определением вы можете ознакомится здесь. Этот этап, как вы сами понимаете, будет работать только с выключенным компьютером, так что нам необходимо будет сохранить всю информацию. Полный код я напишу в конце статьи.
Код на самом деле не такой то уж и страшный, деятельность этого пункта можно разделить на два этапа: создание пакета и его отправка.
Код C#
[DllImport("iphlpapi.dll", ExactSpelling = true)] public static extern int SendARP(int destIp, int srcIP, byte[] macAddr, ref uint physicalAddrLen); private void WakeFunction(string MAC_ADDRESS) { WOLClass client = new WOLClass(); client.Connect(new IPAddress(0xffffffff), 0x2fff); client.SetClientToBrodcastMode(); int counter = 0; //буфер для отправки byte[] bytes = new byte[1024]; //Первые 6 бит 0xFF for (int y = 0; y < 6; y++) bytes[counter++] = 0xFF; //Повторим MAC адрес 16 раз for (int y = 0; y < 16; y++) { int i = 0; for (int z = 0; z < 6; z++) { bytes[counter++] = byte.Parse(MAC_ADDRESS.Substring(i, 2), NumberStyles.HexNumber); i += 2; } } //Отправляем полученный магический пакет int reterned_value = client.Send(bytes, 1024); } public class WOLClass : UdpClient { public WOLClass() : base() { } //Установим broadcast для отправки сообщений public void SetClientToBrodcastMode() { if (this.Active) this.Client.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.Broadcast, 0); } }
Вот, наверное, и всё, я постарался пробежаться по основным моментам несложной, но очень интересной программы. Для статьи я наполнил эту программу еще некоторым функционалом, чтобы как-то разнообразить ее. Если кого то заинтересует — здесь есть, что взять для себя. Ниже представлен весь код:
<Window x:Class="Network.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="497" Width="872" Closing="Window_Closing"> <Grid> <ListView Margin="12,84,12,12" Name="listView1"> <ListView.ContextMenu> <ContextMenu > <MenuItem Header="Копировать"> <MenuItem Header="IP-adress" Name="copyIP" Click="copyIP_Click" /> <MenuItem Header="HostName" Name="copyName" Click="copyName_Click" /> <MenuItem Header="Mac-adress" Name="copyMacAddress" Click="copyMacAddress_Click" /> </MenuItem> <MenuItem Header="Очистисть список" Name="ClearList" Click="ClearList_Click" /> <MenuItem Header="Сохранить список"/> <MenuItem Header="Действия"> <MenuItem Header="Удаленное включение" Name="PowerOn" Click="PowerOn_Click" /> <MenuItem Header="Удаленное завершение" IsEnabled="False" /> </MenuItem> <MenuItem Header="Отмена"/> </ContextMenu> </ListView.ContextMenu> <ListView.View> <GridView> <GridView.Columns> <GridViewColumn Header="IP-Адрес" DisplayMemberBinding="{Binding Path=ipAdress}" Width="200"></GridViewColumn> <GridViewColumn Header="HostName" DisplayMemberBinding="{Binding Path=nameComputer}" Width="250"></GridViewColumn> <GridViewColumn Header="Mac адрес" DisplayMemberBinding="{Binding Path=MacAdress}" Width="250"></GridViewColumn> </GridView.Columns> </GridView> </ListView.View> </ListView> <TextBox Height="23" HorizontalAlignment="Left" Margin="221,15,0,0" Name="textBox1" VerticalAlignment="Top" Width="164" /> <Label Height="27" HorizontalAlignment="Left" Margin="219,36,0,0" Name="label1" VerticalAlignment="Top" Width="316"> IP-адресс/Host-имя компьютера, например: 192.168.1.1 </Label> <Button Content="Начать сканирование" Height="52" HorizontalAlignment="Left" Margin="12,15,0,0" Name="button2" VerticalAlignment="Top" Width="153" Click="button2_Click" /> <Label Content="Ваш IP:" Height="28" HorizontalAlignment="Right" Margin="0,1,125,0" Name="label2" VerticalAlignment="Top" Width="50" /> <Label Height="28" Margin="0,1,2,0" Name="label3" VerticalAlignment="Top" HorizontalAlignment="Right" Width="117" /> <Button Content="Проверить" Height="23" HorizontalAlignment="Left" Margin="415,15,0,0" Name="button1" VerticalAlignment="Top" Width="120" Click="button1_Click_1" /> <ComboBox Height="23" HorizontalAlignment="Right" Margin="0,45,62,0" Name="comboBox1" VerticalAlignment="Top" Width="199" SelectionChanged="comboBox1_SelectionChanged" /> <Grid Background="#FF9D9D9D" HorizontalAlignment="Right" Margin="0,91,-191,10" Name="rectangle1" Width="178"> <Label Content="IP- адрес" Height="28" Margin="16,25,23,0" Name="label4" VerticalAlignment="Top" /> <TextBox Height="23" HorizontalAlignment="Left" Margin="16,53,0,0" Name="textBox2" VerticalAlignment="Top" Width="139" /> <TextBox Height="23" HorizontalAlignment="Left" Margin="16,124,0,0" Name="textBox3" VerticalAlignment="Top" Width="139" /> <Label Content="HostName" Height="28" Margin="16,90,23,0" Name="label5" VerticalAlignment="Top" /> <TextBox Height="23" HorizontalAlignment="Left" Margin="16,203,0,0" Name="textBox4" VerticalAlignment="Top" Width="139" /> <Label Content="Mac-address" Height="28" Margin="16,169,23,0" Name="label6" VerticalAlignment="Top" /> <Button Content="Включить" Height="23" HorizontalAlignment="Left" Margin="16,0,0,58" Name="button3" VerticalAlignment="Bottom" Width="139" Click="button3_Click" /> <Button Content="Закрыть" Height="23" HorizontalAlignment="Left" Margin="16,0,0,19" Name="button4" VerticalAlignment="Bottom" Width="139" Click="button4_Click" /> </Grid> </Grid> </Window>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Net; using System.Runtime.InteropServices; using System.Threading; using System.Net.Sockets; using System.Globalization; using System.IO; namespace Network { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { [DllImport("iphlpapi.dll", ExactSpelling = true)] public static extern int SendARP(int destIp, int srcIP, byte[] macAddr, ref uint physicalAddrLen); List<TableHost> _host = new List<TableHost>(); string hostname = ""; IPHostEntry entry ; string[] ipToString = new string[4]; public MainWindow() { InitializeComponent(); //string[] first = adress.ToString().Split('.'); //string[] second = IPAddress.Parse("192.168.1.0").ToString().Split('.'); // Получение имени компьютера. String host = System.Net.Dns.GetHostName(); // Получение ip-адреса. System.Net.IPAddress ip = System.Net.Dns.GetHostByName(host).AddressList[0]; // Показ адреса в label'е. label3.Content = ip.ToString(); ipToString = ip.ToString().Split('.'); ADd(); } string[] ipadressText; string[] hostnameText; string[] macaddressText; private void ADd() { string[] str = File.ReadAllLines("IPMAC.txt"); ipadressText = new string[str.Length]; hostnameText = new string[str.Length]; macaddressText = new string[str.Length]; for (int i = 0; i < str.Length; i++) { string[] s = str[i].Split('#'); ipadressText[i] = s[0]; hostnameText[i] = s[1]; macaddressText[i] = s[2]; comboBox1.Items.Add(s[1]); } } private void WakeFunction(string MAC_ADDRESS) { WOLClass client = new WOLClass(); client.Connect(new IPAddress(0xffffffff), 0x2fff); client.SetClientToBrodcastMode(); int counter = 0; //буффер для отправки byte[] bytes = new byte[1024]; //Первые 6 бит 0xFF for (int y = 0; y < 6; y++) bytes[counter++] = 0xFF; //Повторим MAC адрес 16 раз for (int y = 0; y < 16; y++) { int i = 0; for (int z = 0; z < 6; z++) { bytes[counter++] = byte.Parse(MAC_ADDRESS.Substring(i, 2), NumberStyles.HexNumber); i += 2; } } //Отправляем полученый магический пакет int reterned_value = client.Send(bytes, 1024); } private void GetInform(string textName) { string IP_Address = ""; string HostName = ""; string MacAddress = ""; try { //Проверяем существует ли IP entry = Dns.GetHostEntry(textName); foreach (IPAddress a in entry.AddressList) { IP_Address = a.ToString(); break; } //Получаем HostName HostName = entry.HostName; //Получаем Mac-address IPAddress dst = IPAddress.Parse(textName); byte[] macAddr = new byte[6]; uint macAddrLen = (uint)macAddr.Length; if (SendARP(BitConverter.ToInt32(dst.GetAddressBytes(), 0), 0, macAddr, ref macAddrLen) != 0) throw new InvalidOperationException("SendARP failed."); string[] str = new string[(int)macAddrLen]; for (int i = 0; i < macAddrLen; i++) str[i] = macAddr[i].ToString("x2"); MacAddress = string.Join(":", str); //Далее, если всё успешно, добавляем все данные в список, после чего выводим всё в ListView Dispatcher.Invoke(new Action(() => { _host.Add(new TableHost() { ipAdress = IP_Address, nameComputer = HostName, MacAdress = MacAddress }); listView1.ItemsSource = null; listView1.ItemsSource = _host; })); } catch { } } private void button1_Click(object sender, RoutedEventArgs e) { //string message = ""; //Print(GetIP(textBox1.Text), GetHostName(textBox1.Text), GetMac(message)); } private void button2_Click(object sender, RoutedEventArgs e) { int i = int.Parse(ipToString[0]); int j = int.Parse(ipToString[1]); { for(int k = 0;k<6;k++) { for (int m = 0; m < 254; m++) { Thread _thread = new Thread(() => GetInform(string.Format("{0}.{1}.{2}.{3}", i.ToString(), j.ToString(), k.ToString(), m.ToString()))); _thread.Start(); } } } } private void PowerOn_Click(object sender, RoutedEventArgs e) { try { WakeFunction(_host[listView1.SelectedIndex].MacAdress.ToString().Replace(":", "")); MessageBox.Show("Операция выполнена успешно!", "Внимание!", MessageBoxButton.OK, MessageBoxImage.Information); } catch { MessageBox.Show("Запрос некорретный!","Внимание!Ошибка!",MessageBoxButton.OK,MessageBoxImage.Error); } } private void ClearList_Click(object sender, RoutedEventArgs e) { _host.Clear(); listView1.Items.Refresh(); } private void copyIP_Click(object sender, RoutedEventArgs e) { Clipboard.SetText(_host[listView1.SelectedIndex].ipAdress.ToString()); } private void copyName_Click(object sender, RoutedEventArgs e) { Clipboard.SetText(_host[listView1.SelectedIndex].nameComputer.ToString()); } private void copyMacAddress_Click(object sender, RoutedEventArgs e) { Clipboard.SetText(_host[listView1.SelectedIndex].MacAdress.ToString()); } private void button1_Click_1(object sender, RoutedEventArgs e) { GetInform(textBox1.Text); } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { 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(); } void P() { for (double i = -192; i < 10; i += 0.004) { Dispatcher.Invoke(new Action(() => { rectangle1.Margin = new Thickness(0, 101, i, 10); })); }//12,0,12,1 } private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e) { //ii = rectangle1.Width; textBox2.Text = ipadressText[comboBox1.SelectedIndex]; textBox3.Text = comboBox1.SelectedItem.ToString(); textBox4.Text = macaddressText[comboBox1.SelectedIndex]; Thread thread = new Thread(P); thread.Start(); } private void button3_Click(object sender, RoutedEventArgs e) { try { WakeFunction(textBox4.Text.Replace(":", "")); MessageBox.Show("Операция выполнена успешно!", "Внимание!", MessageBoxButton.OK, MessageBoxImage.Information); } catch { MessageBox.Show("Запрос некорретный!", "Внимание!Ошибка!", MessageBoxButton.OK, MessageBoxImage.Error); } } private void button4_Click(object sender, RoutedEventArgs e) { Thread thread = new Thread(CLose); thread.Start(); } void CLose() { for (double i = 9; i > -193; i -= 0.004) { Dispatcher.Invoke(new Action(() => { rectangle1.Margin = new Thickness(0, 101, i, 10); })); }//12,0,12,1 } } class TableHost { public string ipAdress { get; set; } public string nameComputer { get; set; } public string MacAdress { get; set; } } public class WOLClass : UdpClient { public WOLClass() : base() { } //Установим broadcast для отправки сообщений public void SetClientToBrodcastMode() { if (this.Active) this.Client.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.Broadcast, 0); } } }
ссылка на оригинал статьи http://habrahabr.ru/post/262699/
Добавить комментарий