大家平常用的网管类软件中都少不了远程控制功能,最常见的就是远程关机\重启\注销, 为什么我们可以从服务器发送指令就可以命令工作站关闭呢? 从编程的角度去想, 难度操作系统中有什么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 等协议传输到服务端,服务端再把图片显现出来,就实现了远程监看屏幕,实际总结一句话:“远程的事,都是自己做的”。
参与讨论远程关机/重启/注销的原理和代码实现,请点击进入网吧论坛