一个定时网络唤醒的Windows 2000服务(Service)程序_zgqtxwd的博客-程序员宅基地

技术标签: delphi  网络  service  服务器  thread  windows  

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

单位有两台服务器,一台的Bios中有定时启动的功能,而另外一台没有。所以每天早上到单位后第一件事情就是要去按一下这台服务器的电源开关来开机,不甚其烦!今天编写了一个定时网络唤醒服务Service程序,安装在第一台服务器上,这样当第一台服务器启动后,如果到了时间,就会自动通过网络发送WakeOnLine(WOL)的广播包来唤醒另外一台服务器。

步骤:

启动Delphi,File-New-Other-Server Application,然后定义该Service的属性,如图:

保存文件名称为WakeOnlineSrv.pas,该单元的代码如下:

unit WakeOnlineSrv;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs,
  WakeOnlineExecuteThread;

type
  TWakeOnLineServer = class(TService)
    procedure ServiceStart(Sender: TService; var Started: Boolean);
    procedure ServiceStop(Sender: TService; var Stopped: Boolean);
    procedure ServicePause(Sender: TService; var Paused: Boolean);
    procedure ServiceContinue(Sender: TService; var Continued: Boolean);
  private
    { Private declarations }
    ThdWakeOnline:TWakeOnline;
  public
    function GetServiceController: TServiceController; override;
    { Public declarations }
  end;

var
  WakeOnLineServer: TWakeOnLineServer;

implementation

{$R *.DFM}

procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  WakeOnLineServer.Controller(CtrlCode);
end;

function TWakeOnLineServer.GetServiceController: TServiceController;
begin
  Result:=ServiceController;
end;

procedure TWakeOnLineServer.ServiceStart(Sender: TService;
  var Started: Boolean);
begin
//启动服务
  ThdWakeOnline:=TWakeOnline.Create(False);
  Started:=True;
end;

procedure TWakeOnLineServer.ServiceStop(Sender: TService;
  var Stopped: Boolean);
begin
//停止服务
  ThdWakeOnline.Terminate;
  Stopped:=True;
end;

procedure TWakeOnLineServer.ServicePause(Sender: TService;
  var Paused: Boolean);
begin
//暂停服务
  ThdWakeOnline.Suspend;
  Paused:=True;
end;

procedure TWakeOnLineServer.ServiceContinue(Sender: TService;
  var Continued: Boolean);
begin
//恢复服务
  ThdWakeOnline.Resume;
  Continued:=True;
end;

end.

再从File-New-Other-Thread Object,新建一个单元文件,保存文件名称为WakeOnlineExecuteThread.pas,代码如下:

unit WakeOnlineExecuteThread;

interface

uses
  Classes, IdUDPClient, SysUtils;

Const
  WakeUpTime='07:50';  //Notice that Not 7:50!
  StopSendTime='07:51';
  TargetComputerMacAddress='00025556E5C5';

type
  TWakeOnLine = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

var Sent:Boolean=False;

implementation

{ Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure WakeOnLine.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ WakeOnLine }

procedure TWakeOnLine.Execute;
var
  MacAddr:String;
  FUDP: TIdUDPClient;
  SendCode:string;
  I,J: Integer;
  Bin: String[6];
begin
{ Place thread code here }
  //线程终止时自动释放
  Self.FreeOnTerminate:=True;
  //发送标志
  Sent:=False;
  //如果线程没有被终止则运行下面的循环
  while not Terminated do
  begin
    //如果没有发送,并且已经到了发送的时间
    if (not Sent) and (Copy(FormatDateTime('hh:mm:ss',Now),1,5)=WakeUpTime) then
    begin
      //开始发送
      MacAddr:=TargetComputerMacAddress;

      FUDP:=TIdUDPClient.Create(nil);
      try
        FUDP.Port:=7;
        FUDP.Host:='10.10.10.2';
        FUDP.Active:=True;

        HextoBin(PChar(MacAddr),@Bin,6);
        SendCode:=StringofChar(#255,6);

        //填充缓冲区
        for I:=0 to 15 do
          for J:=0 to 5 do
            SendCode:=SendCode+Bin[J];

        //连续发送6次,保险啊。。。
        for I:=0 to 5 do
          FUDP.Broadcast(SendCode,7);

      finally
        FUDP.Free;
      end;

      Sent:=True;

    end else

    begin
      //如果已经发送,并且已经到了发送时间的下一分钟,则重置发送标志以备下一天还能发送
      if Sent and (Copy(FormatDateTime('hh:mm:ss',Now),1,5)=StopSendTime) then
         Sent:=False;

      //休息30秒,避免浪费资源
      Sleep(30000);
    end;

    //如果有终止信号则终止
    if Terminated then Break;

  end;

end;

end.

最后保存工程文件名称为WakeOnline.dpr,内容如下:

program WakeOnline;

uses
  SvcMgr,
  WakeOnlineSrv in 'WakeOnlineSrv.pas' {WakeOnLineServer: TService},
  WakeOnlineExecuteThread in 'WakeOnlineExecuteThread.pas';

{$R *.RES}

begin
  Application.Initialize;
  Application.CreateForm(TWakeOnLineServer, WakeOnLineServer);
  Application.Run;
end.

给这个服务程序选择一个合适的图标,最后编译生成一个名称为WakeOnLine.Exe可执行文件。

到Cmd窗口去安装该服务程序:执行:WakeOnLine -install,会提示服务已经成功安装:

然后鼠标右击我的电脑-管理-服务和应用程序服务,然后找到刚刚安装好的服务:Wake On Line Server,

可以看到它还没有启动,现在双击它,点击启动:


我在程序中指定的时间是早上7:50分发送广播,启动一个网络包抓取程序,将时间调节到早上7:49来测试一下,等带一会儿,看看抓到了什么:

目标机器启动啦。。。

(说明:Delphi 7编译;CISCO 2950交换机;被唤醒的是IBM X205服务器,注意将Bios中的Wake On Line选项Enable)

[email protected]

2004-6-2

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zgqtxwd/article/details/2346879

智能推荐

神经网络 Python TensorFlow 正则化(学习笔记)_Monica_Zzz的博客-程序员宅基地

#生成模拟数据集import tensorflow as tf import matplotlib.pyplot as pltimport numpy as npdata=[]label=[]np.random.seed(0)#以原点为圆心,半径为1的圆把散点划分为红蓝两部分,加入随机噪音for i in range(150): x1=np.random.uniform...

gcd库函数_把键盘给我敲烂!!的博客-程序员宅基地_gcd库函数

相信大家学习过如何写gcd函数,那今天就分享下库函数gcd以及最小公倍数代码实现如下(c++)#include &lt;bits/stdc++.h&gt;#include&lt;algorithm&gt;//gcd所在库,此库为编译器自带!~~~~~using namespace std;int main(){ int k; int a,b; cin&gt;&g...

GJB5000A-2008军用软件研制 能力成熟度模型_shenmanli的博客-程序员宅基地

为了一步提高科研院所、高校、部队以及参与军用软件开发的企业的研发管理人员和设计人员对GJB5000A-2008标准的理解,提升软件研制能力和管理水平,确保军用软件开发过程的成熟度,提高军用软件产品的质量,中科院计算所培训中心定于2013年10月16日至18日在北京举办《GJB5000A-2008军用软件研制能力成熟度模型》理解培训班。现将具体事宜通知如下:一、培训对象科研院所、部队、参与军

Python数据结构之链表_你先画个包络面的博客-程序员宅基地

用Python面向对象语言实现数据结构链表

基于Java实现大学生求职招聘信息网站系统_奥斯卡1号的博客-程序员宅基地_java实现招聘网站

摘要设计:当前社会竞争日趋激烈,“找工作难”已成为社会的一大难题。问题的关键在于求职和招聘的人员都陷入了如何找到适合自己的工作以及如何招到合格的人才来填补公司空缺的这一矛盾中。在国内,网络招聘发展迅速。首先因为网上投递的简历比较多,而且应聘者素质较高。还有,网络招聘的优点是快捷,方便,招聘网站所提供的一些服务还可以帮助企业筛选简历,提高企业的工作效率。另外,网络招聘上花的成本远远低于传统的任何一种方式,这也是企业选择网络招聘的一个重要原因。点击查看完整视频https://www.bilibil...

Kubernetes运维之使用Prometheus全方位监控K8S_victoruu的博客-程序员宅基地_k8s prometheus

目录:Prometheus架构 K8S监控指标及实现思路 在K8S平台部署Prometheus 基于K8S服务发现的配置解析 在K8S平台部署Grafana 监控K8S集群中Pod、Node、资源对象 使用Grafana可视化展示Prometheus监控数据 告警规则与告警通知说在前面的话,现在监控首选的话,肯定是Prometheus+Grafana,也就是很多大型公司也都在用,像RBM,360,网易,基本都是使用这一套监控系统。一、Prometheus 是什么?Prometheu

随便推点

Android Studio 无法使用 Profile_songzi1228的博客-程序员宅基地

目录1、问题描述2、解决方案查找(暂未解决)2.1、搜索1、问题描述环境:Android Studio 3.0.1Android Studio的所有项目在使用ProfileAPP功能的时候,会出现闪退问题。logcat也没报错,在Run那儿出现了如下信息I/tpc.imon.rddan: Rejecting re-init on previously-fa...

兔子视频 OpenGL 客户端技术解析_波_爷的博客-程序员宅基地

兔子视频一款面向智能机顶盒和智能电视的在线视频聚合导航应用。整个应用的界面使用OpenGL实现,并使用主动渲染方式让界面不断的循环绘制,OpenGL帧率较高,所以里面的动画看起来非常流畅。整个页面简洁大气,操作不繁多,交互简洁而信息量并未减少,这也是使用OpenGL来实现的一个原因吧。1、欢迎页  其使用的图片资源: 这个页面不能确定是使用什么实现的,因为A

Socket实例代码_荣-的博客-程序员宅基地

最近在用Socket,不是很明白,但是总算是实现了socket传信息。现在把代码贴在这里:这是一段MFC中的代码:服务器端接受数据的代码:static DWORD WINAPI RunSocket(LPVOID lpvoid);int CSocketAppView::OnCreate(LPCREATESTRUCT lpCreateStruct) {    if (CView::On

linux摄像头 sdl,Linux音视频(SDL与YUV)_黔子的博客-程序员宅基地

SDL是一个比较底层的音视频处理库,很多UI系统的内核都用到它,我们还可以用它来处理摄像头中YUV数据。拓展:SDL(SimpleDirectMediaLayer)是一个跨平台的底层开发库,提供操作诸如音频、键盘、鼠标、游戏杆以及显卡等硬件的方法,被很多多媒体播放器、模拟器和流行游戏所使用,SDL支持Windows、MacOS、Linux、iOS以及Android,也就是说你目所能及的几乎所...

实现一个函数,可以左旋字符串中的k个字符_一氧化二氢的执着的博客-程序员宅基地

1.实现一个函数,可以左旋字符串中的k个字符。ABCD左旋一个字符得到BCDAABCD左旋两个字符得到CDAB2.判断一个字符串是否为另外一个字符串旋转之后的字符串。例如:给定s1 = AABCD和s2 = BCDAA,返回1给定s1 = abcd和s2 = ACBD,返回0.AABCD左旋一个字符得到ABCDAAABCD左旋两个字符得到BCDAAAABCD右旋一个字符得到DAA...

pytest文档2-用例运行规则_上海-悠悠的博客-程序员宅基地

用例设计原则文件名以test_*.py文件和*_test.py以test_开头的函数以Test开头的类,并且不能带有 init 方法以test_开头的方法所有的包pakege必须要有__init__.py文件help帮助1.查看pytest命令行参数,可以用pytest -h 或pytest --help查看C:\Users\admin&gt;pytest -husage: pytest [options] [file_or_dir] [file_or_dir] [...]pos

推荐文章

热门文章

相关标签