一个定时网络唤醒的Windows 2000服务(Service)程序

单位有两台服务器,一台的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)

iLittle@FAT

2004-6-2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一款定时/循环执行任务的绿色小软件,可以用来定时执行程序、DOS命令、从HTTP服务器下载程序运行、结束进程、 模拟按键、发送EMAIL、网络唤醒、消息提示、关机、重启、注销、锁定、待机等操作,都是本人曾经所需要的功能!   合理使用和搭配软件的各功能,可做更多事情!可供对系统较了解的人自由发挥。 提示: a. 显示主窗口热键Ctrl+F1(可在设置里自定义) b. OnTimer.exe /h 启动隐藏,但不隐藏托盘图标除非使用OnTimer.exe /h-all c. 如果想更改消息提示背景只要找张238x139(其他尺寸软件会缩放)的图片替换OnTimer.jpg d. 普通运行、参数运行、 执行DOS “备注”开头为“-h”则隐藏执行 e. 关机、重启、注销、锁定、待机 “内容”开头为数字则执行前倒计时(可选择取消) 1.普通运行:  可以打开程序,目录,网站,文件,和Windows运行一样,只是不能带参数 如: [内容]http://www.yryz.net [内容]d:\mp3\爱上你是个错.mp3(可实现音乐闹钟) 2.参数运行: 可以带参数运行程序 如: [内容]shutdown -s [内容]ping www.baidu.com 3.下载运行:你可以从网上下载文件并执行 如: [内容]http://www.yryz.net/soft/OnTimer.rar [内容]http://dl_dir.qq.com/qqfile/qq/QQ2009/qq2009sp6_installer.exe 4.结束进程: 以最高权限结束进程,可以结束系统进程(winlogon.exe)! 如: [内容]QQ.exe 5.执行DOS: 就是CMD啦(dir del ...) [内容]del c:\*.log /q /s 6.模拟按键: 用来发送按键(附录有相关按键说明) 如: [内容]^%z 相当于按了Ctrl+Alt+z ,QQ出来了吧!…… 7.发送邮件: 用来定时发送Email的,当然你要先设置好SMTP,也就是用来发信的账号,然后就可以添加任务了, [内容]邮件内容 [参数]收信地址 注意: 如果你只是想发送文字,就直接在[内容]中输入,如: 生日快乐! 如果是想发送文本文件,那就在[内容]中输入文件路径如:c:\boot.ini 程序执行此操作时,会先内容是否为存在的文件,否则就把内容当作文字发送! 8.网络唤醒:  用来远程开机,[内容]中输入MAC地址如:00-e0-4d-df-7e-8a 9.消息提示:  用来定时提醒的,在屏幕的右下角以动画形式显示. 10.关闭系统 11.重启系统 12.注销登陆 13.锁定系统 14.系统待机 例: ------------------------ 先: 执行DOS: ipconfig /all >c:\ip.txt 再: 发送邮件: c:\ip.txt 可用于获得ADSL的动态IP,知道的人应该了解用处! ---------------------------------- 20110330 v1.3d - 修复在Windows 7下按“Alt”键按钮消失的BUG - 修复权限问题导致“随系统启动”无效 20101205 v1.3c + 关机等任务支持倒计时,以便取消执行 * 优化列表显示效果 20101128 v1.3b + 普通运行、参数运行、 执行DOS 支持隐藏执行 + 双击任务即可编辑 - 修复“移动”->“尾部”报错 - 修复分类切换时,任务状态显示不正确 * 调整执行次数显示 20101125 v1.3a + 支持任务分类管理(可拖动) + 支持“每月”任务 + 支持任务排序(上下移动任务,可拖动) + 支持任务执行次数存储 + 支持“内容”、“参数/备注”搜索 + 支持临时暂停所有任务 * 一些细节改进和BUG修复 ! 因数据库结构有变动,要使用原来的数据库(OnTimer.db),可执行 OnTimer.exe /update,当然出现异常时软件也会提示你修复. 20101020 v1.2h - 修复软件中文目录支持问题(数据库读取异常) - 修复托盘图标重建问题 + 添加任务状态托盘提示(活动任务/总任务) * 调整显示字体和列表排序 20101018 v1.2g + 加入“系统待机”功能 + 设置中加入“随系统启动”选项 + 任务列表支持点击“表头”进行排序 + 支持给任务添加备注 * 优化一些小细节 - 修复Win7下添加任务时提示“时间格式有误”的BUG 20100903 v1.2f * 优化消息提示框,使其提示消息时不影响你的工作 * 调整了任务类型的顺序,可能会导致旧版任务类型不正常,更新时请注意 * 调整任务列表顺序,把新添加的任务放到最前面 20100623 v1.2e * 改进列表选择框 * 窗口焦点设置(热键唤醒时) - 去掉提示消息窗口自动关闭 + 可自定义热键 ! 因数据库结构有变动,使用 OnTime.exe /12d-12e 启动就可把旧版的数据库转换成v1.2e版 20100511 v1.2d % 解决多任务时列表闪烁问题。 % 修复计时部分一些Bug!(星期) 20100510 v1.2c + 加入按星期执行!并优化计时部分。 20100510 v1.2b * 重写,效果更好,并作大量优化!  + 使用加密SQLite存储数据。 2008 v1.2  边学边做自己用。 按键附录: Shift + Ctrl ^ Alt % Enter ~ 以下按键要用{}括起来: BKSP, BS, BACKSPACE BREAK CAPSLOCK CLEAR DEL DELETE DOWN END ENTER ESC ESCAPE F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 HELP HOME INS LEFT NUMLOCK PGDN PGUP PRTSC RIGHT SCROLLLOCK TAB UP WIN ( ) ~ % ^ + 可参考下例重复发送某按键: {DEL 4} ;连续4次按下 DEL 键 {S 30} ;发送30个字符“S” +{TAB 4} ;连续4次按下 SHIFT+TAB -------------------------------------------------------- SendMail.log是的日志代码,可参考下表 邮件服务返回代码含义 500 格式错误,命令不可识别(此错误也包括命令行过长) 501 参数格式错误 502 命令不可实现 503 错误的命令序列 504 命令参数不可实现 211 系统状态或系统帮助响应 214 帮助信息 220 服务就绪 221 服务关闭传输信道 421 服务未就绪,关闭传输信道(当必须关闭时,此应答可以作为对任何命令的响应) 250 要求的邮件操作完成 251 用户非本地,将转发向 450 要求的邮件操作未完成,邮箱不可用(例如,邮箱忙) 550 要求的邮件操作未完成,邮箱不可用(例如,邮箱未找到,或不可访问) 451 放弃要求的操作;处理过程中出错 551 用户非本地,请尝试 452 系统存储不足,要求的操作未执行 552 过量的存储分配,要求的操作未执行 553 邮箱名不可用,要求的操作未执行(例如邮箱格式错误) 354 开始邮件输入,以.结束 554 操作失败 535 用户验证失败 235 用户验证成功 334 等待用户输入验证信息
### 回答1: 以下是一个简单的Windows定时关机程序: 1. 打开“开始”菜单,输入“cmd”,然后按“Enter”键打开命令提示符窗口。 2. 在命令提示符窗口中输入“shutdown -s -t 3600”,其中3600表示关机延迟时间,单位为秒。 3. 再次按下“Enter”键,即可完成定时关机程序的设置。 ### 回答2: 要写一个Windows定时关机的程序,可以使用批处理脚本或编程语言来实现。以下是一个使用批处理脚本的示例: 1. 首先,打开文本编辑器(如记事本)并创建一个新的文本文件。 2. 在文本文件中输入以下命令: ```batch @echo off echo 正在设置定时关机... set /p hours=请输入定时时间(小时): set /p minutes=请输入定时时间(分钟): set /p seconds=请输入定时时间(秒): set /a total_time=hours*3600 + minutes*60 + seconds timeout %total_time% shutdown /s /t 0 ``` 3. 将上述文本保存为一个批处理脚本文件,例如shutdown.bat(注意扩展名必须是.bat)。 4. 双击运行该脚本文件,程序将提示您输入定时关机的时间(以小时、分钟和秒为单位)。 5. 输入所需的时间后,计算机将等待指定的时间长度后自动关机。 这个批处理脚本的工作原理是: - 关闭脚本的输出显示(@echo off)。 - 用户被提示输入定时时间(小时、分钟和秒)。 - 输入的时间被转换为秒(total_time = hours * 3600 + minutes * 60 + seconds)。 - 程序等待指定的时间长度(timeout %total_time%)。 - 最后,计算机执行关机命令(shutdown /s /t 0),将计算机关闭。 希望这个简单的批处理脚本可以满足您的Windows定时关机需求。如果您喜欢编程,也可以使用其他编程语言(如Python、C#等)来实现更复杂的定时关机程序。 ### 回答3: 要编写一个Windows定时关机的程序,可以使用C#编程语言和Windows API来实现。下面是一个示例程序的代码: ```csharp using System; using System.Runtime.InteropServices; class Program { [DllImport("user32.dll")] public static extern int MessageBox(int hWnd, string text, string caption, int type); [DllImport("user32.dll")] public static extern bool ExitWindowsEx(uint uFlags, uint dwReason); static void Main(string[] args) { Console.WriteLine("请输入关机时间(单位:分钟):"); int minutes = int.Parse(Console.ReadLine()); int milliseconds = minutes * 60 * 1000; // 获取系统当前时间 DateTime currentTime = DateTime.Now; // 计算关机时间 DateTime shutdownTime = currentTime.AddMilliseconds(milliseconds); // 显示关机时间 Console.WriteLine("将在 {0} 关机", shutdownTime); // 等待定时关机 while (DateTime.Now < shutdownTime) { // 每秒钟检查一次关机时间是否到达 System.Threading.Thread.Sleep(1000); } // 进行关机操作 ExitWindowsEx(0x00000008 | 0x00000001, 0); // 显示关机消息 MessageBox(0, "计算机即将关机", "关机提示", 0); } } ``` 该程序首先会要求用户输入一个关机时间(以分钟为单位),然后通过计算得到将来的关机时间,并且在控制台上显示这个关机时间。程序会在计算机时间达到关机时间之前等待。一旦时间到达,程序会调用Windows API函数进行关机操作,并且在屏幕上显示一个关机提示消息框。 请注意,此示例仅适用于Windows操作系统,并且可能需要管理员权限才能成功执行关机操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值