局域网控制(三)——远程关机重启等

来源:互联网 发布:2017如何关闭淘宝店铺 编辑:程序博客网 时间:2024/06/10 22:36

 

3、其他

凡在本地计算机上通过编程可以实现的,在远程计算机上也可以实现,只不过是事件的执行或调用需要指定一个标志或信号即可。下面就介绍几个常用功能的实现过程:

1)关闭计算机

关闭计算机可以采用Windows API中的ExitWindowsEx()函数来实现,也可以直接通过新建Windowscmd进程来调用Shutdown命令实现,使用ExitWindowsEx()函数时要先结束一些正在使用的进程才能正常运行,所以在此介绍采用Shutdown来实现关闭计算机。

由于使用Shutdown命令来执行,首先来看一下Shutdown命令的一些相关参数,如下:

shutdown [-i | -l | -s | -r | -a] [-f] [-m computername] [-t xx] [-c "comment"] [-d up:xx:yy]

其中:i表示显示GUI界面;l表示注销;s表示关闭此计算机;r表示关闭并重新启动此计算机;a表示放弃系统关机; m表示远程计算机关机等操作,后面的参数computername表示计算机名称;t表示设置关闭的时间;c表示注释,后面的参数comment表示注释内容;d表示关闭原因代码。

下面举例来说明一下,如果要60秒后关闭一个计算机直接点击“开始”菜单,打开“运行”,输入“shutdown -s -t 60,如下图所示,然后点击“确定”按钮:

输入“shutdown a”,即可取消关闭计算机。

下面就可以通过新建一个cmd的进程,然后再输入Shutdown的关机命令即可实现。新建进程需要使用Process类,所以需要引用命名空间System.Diagnostics,如下:

【客户端】:

using System.Diagnostics;

要调用cmd进程,直接新建一个进程对象,设置其FileName,然后在其WriteLine方法中写入关机命令,如下:

            Process p = new Process();

            p.StartInfo.FileName = "cmd.exe";

            p.StartInfo.RedirectStandardError = true;

            p.StartInfo.RedirectStandardInput = true;

            p.StartInfo.RedirectStandardOutput = true;

            p.StartInfo.UseShellExecute = false;           

            p.Start();

            p.StandardInput.WriteLine("shutdown -s");

            p.StandardInput.WriteLine("Exit");

            p.WaitForExit();

            p.Close();

按此思路可以设计关闭计算机、重启计算机和注销。如下关闭计算机代码:

【客户端】:

            DialogResult dialogResult = MessageBox.Show("是否关闭计算机?", "警告!", MessageBoxButtons.YesNo);

            if (dialogResult.ToString() == "Yes")

            {

                Process p = new Process();

                p.StartInfo.FileName = "cmd.exe";

                p.StartInfo.RedirectStandardError = true;

                p.StartInfo.RedirectStandardInput = true;

                p.StartInfo.RedirectStandardOutput = true;

                p.StartInfo.UseShellExecute = false;

                p.Start();

                p.StandardInput.WriteLine("shutdown -s");

                p.StandardInput.WriteLine("Exit");

                p.WaitForExit();

                p.Close();

            }

重新启动计算机:

【客户端】:

            DialogResult dialogResult = MessageBox.Show("是否重新启动计算机?", "警告!", MessageBoxButtons.YesNo);

            if (dialogResult.ToString() == "Yes")

            {

                Process p = new Process();

                p.StartInfo.FileName = "cmd.exe";

                p.StartInfo.RedirectStandardError = true;

                p.StartInfo.RedirectStandardInput = true;

                p.StartInfo.RedirectStandardOutput = true;

                p.StartInfo.UseShellExecute = false;

                p.Start();

                p.StandardInput.WriteLine("shutdown -r");

                p.StandardInput.WriteLine("Exit");

                p.WaitForExit();

                p.Close();

            }

注销计算机:

【客户端】:

            DialogResult dialogResult = MessageBox.Show("是否重新启动计算机?", "警告!", MessageBoxButtons.YesNo);

            if (dialogResult.ToString() == "Yes")

            {

                Process p = new Process();

                p.StartInfo.FileName = "cmd.exe";

                p.StartInfo.RedirectStandardError = true;

                p.StartInfo.RedirectStandardInput = true;

                p.StartInfo.RedirectStandardOutput = true;

                p.StartInfo.UseShellExecute = false;

                p.Start();

                p.StandardInput.WriteLine("shutdown -l");

                p.StandardInput.WriteLine("Exit");

                p.WaitForExit();

                p.Close();

            }

2)远程关机

由于防火墙等原因,直接使用Shutdown命令不一定能实现远程关机,所以要实现远程关机还需要向客户端发送指定指令,在客户端根据该指令来执行相应操作。如在控制端添加一个按钮,设置其Nametext属性都为“远程关闭计算机”,为其Click()事件添加如下代码:

【控制端】:

        private void 远程关闭计算机_Click(object sender, EventArgs e)

        {

            string message = "SHUTDOWN -S";

            SendMessage(message);

        }

这样控制端就将命令发送至客户端了,同时客户端还需要对这句指令进行解析与识别,然后执行相应操作。首先更改客户端的监听函数Listen(),如下(斜体部分为修改的部分):

【客户端】:

        private void Listen()

        {

            try

            {

                Int32 port = Int32.Parse(portTextBox.Text);

                tcpListener = new TcpListener(port);

                tcpListener.Start();

                while (true)

                {

                    TcpClient client = tcpListener.AcceptTcpClient();

                    NetworkStream stream = client.GetStream();

                    if (stream.CanRead)

                    {

                        string mouseEvent = "";

                        byte[] bytes = new byte[1024];

                        stream.Read(bytes, 0, bytes.Length);

                        mouseEvent = Encoding.ASCII.GetString(bytes);

                        //分解字符串

                        if (mouseEvent.Contains("SHUTDOWN"))

                        {

                            RunWindowsEvent(mouseEvent);

                        }

                        else

                        {

                            int i, mouseX, mouseY, mouseClick;

                            i = mouseEvent.IndexOf(",");

                            mouseX = int.Parse(Microsoft.VisualBasic.Strings.Left(mouseEvent, i));

                            mouseEvent = Microsoft.VisualBasic.Strings.Right(mouseEvent, mouseEvent.Length - i - 1);

                            i = mouseEvent.IndexOf(",");

                            mouseY = int.Parse(Microsoft.VisualBasic.Strings.Left(mouseEvent, i));

                            i = mouseEvent.IndexOf(",");

                            mouseEvent = Microsoft.VisualBasic.Strings.Right(mouseEvent, mouseEvent.Length - i - 1);

                            mouseClick = int.Parse(mouseEvent);

                            //设置鼠标

                            mouseClickEvent(mouseX, mouseY, mouseClick);

                        }

                    }

                    client.Close();

                }

            }

            finally

            {

                tcpListener.Stop();

            }

        }

其中,函数RunWindowsEvent()为自定义的用于执行关机等操作的函数,该函数的具体定义如下:

【客户端】:

        private void RunWindowsEvent(string message)

        {

            Process p = new Process();

            p.StartInfo.FileName = "cmd.exe";

            p.StartInfo.RedirectStandardError = true;

            p.StartInfo.RedirectStandardInput = true;

            p.StartInfo.RedirectStandardOutput = true;

            p.StartInfo.UseShellExecute = false;

            p.Start();

            if (message.Contains("-S"))

            {

                p.StandardInput.WriteLine("SHUTDOWN -S");

            }

            else if (message.Contains("-R"))

            {

                p.StandardInput.WriteLine("SHUTDOWN -R");

            }

            else if (message.Contains("-A"))

            {

                p.StandardInput.WriteLine("SHUTDOWN -A");

            }

            p.StandardInput.WriteLine("Exit");

            p.WaitForExit();

            p.Close();

        }

3)开机自动运行

开机自动运行程序主要是在注册表中新建一个字符串值,设置其值为客户端程序。实现该功能需要使用RegistryKey类来实现,所以首先需要引用命名空间,如下:

using Microsoft.Win32;

然后定义是否开机自动运行的函数SetAutoExec(),其代码如下:

【客户端】:

        public void SetAutoExec(bool IsAuto)

        {

            RegistryKey Reg = Registry.LocalMachine.OpenSubKey(@"SOFTWARE/Microsoft/Windows/CurrentVersion/Run", true);

            if (IsAuto)

            {

                string sFilePath = Application.ExecutablePath;

                Reg.SetValue("局域网控制", sFilePath);

            }

            else

            {

                if (IsAuto == false) Reg.DeleteValue("局域网控制");

            }

        }

4)使用XML保存客户端的设置

客户端在启动时,如果服务器地址或端口变动了,则客户端无法连接到服务器上。为了避免这种情况发送,在客户端启动时,通过一个XML文件将一些主要的参数设置到客户端上,在客户端退出时将这些主要的参数又保存至该XML文件中。这样就不需要每次都去设置如服务器IP地址、端口等,每次客户端启动时就自动根据XML配置文件来设置参数。该配置文件名称为Config.xml,其文件内容如下:

Config.xml:

<?xml version="1.0"?>

<control>

  <IPAddress>192.168.134.195</IPAddress>

  <Port>5000</Port>

  <TimeInterval>1000</TimeInterval>

  <AutoRun>False</AutoRun>

  <UnderControl>True</UnderControl>

</control>

其中<IPAddress>标记的值表示服务器IP地址,<Port>标记的值为端口,<TimeInterval>标记的值表示返回服务器数据的时间间隔,<AutoRun>标记的值表示客户端是否开机自动运行,<UnderControl>标记的值表示客户端是否启动后就开始受控。

所以在FormLoad()事件中要读取该配置文件,如下代码:

【客户端】:

            //先读取配置文件

            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.Load("Config.xml");

            XmlNode root = xmlDoc.SelectSingleNode("control");

 

            IPAddressTextBox.Text = root.ChildNodes[0].InnerText;//查找<IPAddress>

            portTextBox.Text = root.ChildNodes[1].InnerText;//查找<Port>

            timeIntervalTextBox.Text = root.ChildNodes[2].InnerText;//查找<TimeInterval>

            autoRunCheckBoxX.Checked = bool.Parse(root.ChildNodes[3].InnerText);//查找<AutoRun>

            timer1.Enabled = bool.Parse(root.ChildNodes[4].InnerText);//查找<UnderControl> 

            autoControlCheckBoxX.Checked = timer1.Enabled;

FormFormClosing()事件中需要对客户端修改的参数进行保存,以便下次启动客户端时自动加载设置,如下代码:

            //写入修改配置文件

            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.Load("Config.xml");

            XmlNode root = xmlDoc.SelectSingleNode("control");

 

            root.ChildNodes[0].InnerText = IPAddressTextBox.Text;//查找<IPAddress>

            root.ChildNodes[1].InnerText = portTextBox.Text;//查找<Port>

            root.ChildNodes[2].InnerText=timeIntervalTextBox.Text;//查找<TimeInterval>

            root.ChildNodes[3].InnerText=autoRunCheckBoxX.Checked.ToString();//查找<AutoRun>

            root.ChildNodes[4].InnerText = autoControlCheckBoxX.Checked.ToString();//查找<UnderControl> 

            xmlDoc.Save("Config.xml");

运行程序,其界面如下图所示:

图片

 

原创粉丝点击