大家平常用的网管类软件中都少不了远程控制功能,最常见的就是远程关机\重启\注销, 为什么我们可以从服务器发送指令就可以命令工作站关闭呢? 从编程的角度去想, 难度操作系统中有什么API函数是专门用来关闭系统的?又或者服务端发出了什么一连串的指令至使工作站关闭呢?
其实并没有这么复杂,我们就以远程关闭为例,所谓的远程关闭,实际上是工作站自己把自己关掉了;
我们不知道如何远程关闭别人之前,一定要清楚怎么关掉自己;比如写一个关闭系统的函数(关闭本机系统),然后做一个UDP通讯,等待服务器发送指令过来,这个指令可以是非常简单的数字来代表的
比如:1关机(远程关机) 2重启(远程重启) 3注销(远程注销)
也就是说,服务器端发送到客户机的并不是什么神秘的关机指令,可以简单到就是一个数字,收到内部约定的数字,工作站就自己把自己关闭掉,就这么简单.
下面的代码只是一个过程的模拟;我们通过自己编写程序来实现对计算机进行远程关机、远程重启、远程注销;
DELPHI 7 下编译通过
unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdUDPBase, IdUDPServer,IdSocketHandle;
type TForm1 = class(TForm) Button1: TButton; IdUDPServer1: TIdUDPServer; IdUDPServer2: TIdUDPServer; procedure Controls_close(i:integer); procedure operatecomputer(statue:longword); procedure Button1Click(Sender: TObject); procedure IdUDPServer1UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle); private { Private declarations } public { Public declarations }
end;
var Form1: TForm1;
implementation
{$R *.dfm}
//处理系统关闭请求; procedure TForm1.Controls_close(i:integer); begin case i of 1: begin if win32platform =ver_platform_win32_windows then exitwindowsex(ewx_force+ewx_shutdown+ewx_poweroff,32); if win32platform =ver_platform_win32_NT then operatecomputer(ewx_poweroff); //ewx_poweroff 为关机 EWX_FORCE end; 2: begin if win32platform =ver_platform_win32_windows then exitwindowsex(ewx_force+ewx_shutdown+ewx_poweroff,32); if win32platform =ver_platform_win32_NT then operatecomputer(ewx_reboot); //ewx_reboot 为重启 end; 3: begin if win32platform =ver_platform_win32_windows then exitwindowsex(ewx_force+ewx_shutdown+ewx_poweroff,32); if win32platform =ver_platform_win32_NT then operatecomputer(ewx_logoff); //ewx_logoff 为注销 end; 4: begin // end; end; end;
//关闭系统方法; procedure TForm1.operatecomputer(statue:longword); var hToken:THandle; tkp : TOKEN_PRIVILEGES; ReturnLength : DWord;
begin if (not OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_ALL_ACCESS or TOKEN_QUERY, hToken))then begin application.Terminate; end; LookupPrivilegeValue(nil,'SeShutdownPrivilege',tkp.Privileges[0].Luid); tkp.PrivilegeCount := 1; tkp.Privileges[0].Attributes :=SE_PRIVILEGE_ENABLED; ReturnLength :=0; AdjustTokenPrivileges(hToken, FALSE, tkp, 0,nil,ReturnLength);
if (GetLastError() <> ERROR_SUCCESS) then begin application.Terminate; end;
if (not ExitWindowsEx(statue, 0)) then begin application.Terminate; end; end;
//模拟发送; procedure TForm1.Button1Click(Sender: TObject); begin // Controls_close(1); //1关机 2重启 3注销 IdUDPServer2.Send('192.168.1.123',8111,'$3'); end;
//读取消息; procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle); var buffer: pchar; i:integer; begin ShowMessage(ABinding.PeerIP); buffer := GetMemory(1024); AData.Read(buffer^,1024); i:=strtoint(buffer[1]);//只取第二位的数字 Controls_close(i); //调用Controls_close(i)进行相应的处理 FreeMemory(buffer); end;
end.
一般的远程控制其实真的就这样简单,有此网管软件中所带有远程草监看工作站的屏幕,其实原理也是类似的,工作站自已进行了屏幕截图,并把图片转换成JPEG流通过udp 或者tcp 等协议传输到服务端,服务端再把图片显现出来,就实现了远程监看屏幕,实际总结一句话:“远程的事,都是自己做的”。 |