用Delphi实现远程开机,不容易要底层技术!
还是用工具AMD的Magic Pack

解决方案 »

  1.   

    呵呵,我正好做过的首先你要在cmos里改来可以网卡启动然后你的程序要发送个广播,好象是666端口,消息包有固定格式的,如果明早还没解决,我再来,因为现在代码没在这台电脑上:(
      

  2.   

    你真走运,我前天刚刚写了这个程序 :)
    首先是网卡必须支持;以下是我写的代码:
    代码如下:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      SendCode:string;
      TempStr:string;
      i:byte;
    begin
      SendCode:=StringofChar(#255,6);
      for i:=0 to 15 do
          begin
          TempStr:=TempStr
                  +string(char(StrToInt('$' + Copy(Edit1.Text,1,2))))
                  +string(char(StrToInt('$' + Copy(Edit1.Text,4,2))))
                  +string(char(StrToInt('$' + Copy(Edit1.Text,7,2))))
                  +string(char(StrToInt('$' + Copy(Edit1.Text,10,2))))
                  +string(char(StrToInt('$' + Copy(Edit1.Text,13,2))))
                  +string(char(StrToInt('$' + Copy(Edit1.Text,16,2))))
          end;
      SendCode:=SendCode+TempStr;
      UDPSend(SendCode);
    end;
    procedure TForm1.UDPSend(SendCode: String);
    var
      SendMStream:TMemoryStream;
    begin
      SendMStream:=TMemoryStream.Create;
      try
        NMUDP1.ReportLevel:=1;
        NMUDP1.RemoteHost:='100.100.100.255';
        NMUDP1.RemotePort:=7010;
        SendMStream.Write(SendCode[1],length(SendCode));
        NMUDP1.SendStream(SendMStream);
      finally
        SendMStream.Free;
      end;
    end;
      

  3.   

    下面的代码是取得网卡序列号的:
    function GetAdapterInfo(Lana: Char): String;
    var
      Adapter: TAdapterStatus;
      NCB: TNCB;
    begin
      FillChar(NCB, SizeOf(NCB), 0);
      NCB.ncb_command := Char(NCBRESET);
      NCB.ncb_lana_num := Lana;
      if Netbios(@NCB) <> Char(NRC_GOODRET) then
      begin
        Result := 'mac not found';
        Exit; 
      end;  FillChar(NCB, SizeOf(NCB), 0);
      NCB.ncb_command := Char(NCBASTAT);
      NCB.ncb_lana_num := Lana;
      NCB.ncb_callname := '*';  FillChar(Adapter, SizeOf(Adapter), 0);
      NCB.ncb_buffer := @Adapter; 
      NCB.ncb_length := SizeOf(Adapter);
      if Netbios(@NCB) <> Char(NRC_GOODRET) then 
      begin
        Result := 'mac not found'; 
        Exit;
      end;
      Result :=
        IntToHex(Byte(Adapter.adapter_address[0]), 2) + '-' +
        IntToHex(Byte(Adapter.adapter_address[1]), 2) + '-' +
        IntToHex(Byte(Adapter.adapter_address[2]), 2) + '-' +
        IntToHex(Byte(Adapter.adapter_address[3]), 2) + '-' +
        IntToHex(Byte(Adapter.adapter_address[4]), 2) + '-' + 
        IntToHex(Byte(Adapter.adapter_address[5]), 2);
    end; function GetMACAddress: string;
    var
      AdapterList: TLanaEnum;
      NCB: TNCB;
    begin
      FillChar(NCB, SizeOf(NCB), 0);
      NCB.ncb_command := Char(NCBENUM);
      NCB.ncb_buffer := @AdapterList;
      NCB.ncb_length := SizeOf(AdapterList);
      Netbios(@NCB);
      if Byte(AdapterList.length) > 0 then
        Result := GetAdapterInfo(AdapterList.lana[0])
      else
       Result := 'mac not found';
    end;
    结合上面的代码,一个网卡远程开机程序就成功了。
      

  4.   

    (*//
    标题:得到工作组内其他电脑网卡Mac地址
    制作:角落的青苔
    日期:2002-01-25
    E-mail:[email protected]
    //*)得到工作组内其它电脑网卡Mac地址
    unit GetNetMacs;interfaceuses Windows,Classes,SysUtils;type
      PnetResourceArr = ^TNetResource;
      procedure GetServerList(List:TStrings);
      procedure GetUserList(fServer:string;List:TStrings);
    implementation
    procedure GetServerList(List:TStrings);
    type
      {$H+}
      PMyRec = ^MyRec;
      MyRec = Record
                dwScope : Integer;
                dwType : Integer;
                dwDisplayType : Integer;
                dwUsage : Integer;
                LocalName : String;
                RemoteName : String;
                Comment : String;
                Provider : String;
            end;
    {H-}
    var NetResource : TNetResource;
        TempRec : PMyRec;
        Buf : Pointer;
        Count,BufSize,Res : DWORD;
        lphEnum : THandle;
        p : PNetResourceArr;
        i,j : SmallInt;
        NetworkTypeList : TList;
    begin
      NetworkTypeList := TList.Create;
      List.BeginUpdate;
      List.Clear;
      GetMem(Buf, 8192);
      try
        Res:=WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, RESOURCEUSAGE_CONTAINER, nil,lphEnum);
        if Res <> 0 then Raise Exception(Res);
        Count := $FFFFFFFF;
        BufSize := 8192;
        Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
        if Res = ERROR_NO_MORE_ITEMS then Exit;
        if (Res <> 0) then Raise Exception(Res);
        P := PNetResourceArr(Buf);
        for I := 0 to Count-1 do
          begin
            New(TempRec);
            TempRec^.dwScope := P^.dwScope;
            TempRec^.dwType := P^.dwType ;
            TempRec^.dwDisplayType := P^.dwDisplayType ;
            TempRec^.dwUsage := P^.dwUsage ;
            TempRec^.LocalName := StrPas(P^.lpLocalName);
            TempRec^.RemoteName := StrPas(P^.lpRemoteName);
            TempRec^.Comment := StrPas(P^.lpComment);
            TempRec^.Provider := StrPas(P^.lpProvider);
            NetworkTypeList.Add(TempRec);
            Inc(P);
          end;
        Res := WNetCloseEnum(lphEnum);
        if Res <> 0 then Raise Exception(Res);
        for J := 0 to NetworkTypeList.Count-1 do
          begin
            TempRec := NetworkTypeList.Items[J];
            NetResource := TNetResource(TempRec^);
            Res:=WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, RESOURCEUSAGE_CONTAINER, @NetResource,lphEnum);
            if Res <> 0 then Raise Exception(Res);
            while True do
              begin
                Count := $FFFFFFFF;
                BufSize := 8192;
                Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
                if Res = ERROR_NO_MORE_ITEMS then Break;
                if (Res <> 0) then Raise Exception(Res);
                P := PNetResourceArr(Buf);
                for I := 0 to Count - 1 do
                  begin
                    List.Add(P^.lpRemoteName);
                    Inc(P);
                  end;
              end;
          end;
        Res := WNetCloseEnum(lphEnum);
        if Res <> 0 then Raise Exception(Res);
      finally
        FreeMem(Buf);
        NetworkTypeList.Destroy;
      end;
      List.EndUpdate;
    end;procedure GetUserList(fServer:string;List:TStrings);
    var NetResource : TNetResource;
        Buf : Pointer;
        Count,BufSize,Res : DWord;
        Ind : Integer;
        lphEnum : THandle;
        Temp : PNetResourceArr;
    begin
      List.Clear;
      GetMem(Buf, 8192);
      try
        FillChar(NetResource, SizeOf(NetResource), 0);
        NetResource.lpRemoteName := @fServer[1];
        NetResource.dwDisplayType := RESOURCEDISPLAYTYPE_SERVER;
        NetResource.dwUsage := RESOURCEUSAGE_CONTAINER;
        NetResource.dwScope := RESOURCETYPE_DISK;
        Res := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, RESOURCEUSAGE_CONTAINER, @NetResource,lphEnum);
        if Res <> 0 then Exit;
        while True do
          begin
            Count := $FFFFFFFF;
            BufSize := 8192;
            Res := WNetEnumResource(lphEnum, Count, Pointer(Buf), BufSize);
            if Res = ERROR_NO_MORE_ITEMS then Exit;
            if (Res <> 0) then Exit;
            Temp := PNetResourceArr(Buf);
            for Ind := 0 to Count - 1 do
              begin
                List.Add(Temp^.lpRemoteName + 2);
                 // Add all the network usernames to List StringList
                Inc(Temp);
              end;
          end;
        Res := WNetCloseEnum(lphEnum);
        if Res <> 0 then Raise Exception(Res);
      finally
        FreeMem(Buf);
      end;
    end;end.
    ********************************
    procedure TSetup_Main.GetAllStuMacs_BtnClick(Sender: TObject);
    var StuNameListN:Integer;
        LocalName:String;
        GetLineNum:Integer;
        GetLineStr:String;
    begin
      StuName_ListBox.Items.Clear;
      StuMacs_ListBox.Items.Clear;
      Application.MessageBox('依网络状况,该项操作可能耗时2-10分钟,请耐心等候!','提示',MB_OK);
      HadChangeMacs:=True;
      LocalName:=GetDomainName(LocalIPPowersock.LocalIP);
      GetUserList(NetGroup_Edit.Text,StuName_ListBox.Items);
      for StuNameListN:=StuName_ListBox.Items.Count-1 downto 0 do
        if StuName_ListBox.Items[StuNameListN]=LocalName then
          StuName_ListBox.Items.Delete(StuNameListN);
      Application.MessageBox('已经正确得到了所有学生机名!'+#13+#13+'下面将继续取得学生机对应的网卡地址……','提示',MB_OK);
      for StuNameListN:=0 to StuName_ListBox.Items.Count-1 do
        StuMacs_ListBox.Items[StuNameListN]:=GetMacsFromName(StuName_ListBox.Items[StuNameListN]);
      Application.MessageBox('操作成功!','提示',MB_OK);
      DeleteFile('temp.txt');
    end;function TSetup_Main.GetMacsFromName(Name:String):String;
    var Command:String;
        tempResult:String;
    begin
      Command:='Command.com /c nbtstat -a '+Name+' >temp.txt';
      WinExec(Pchar(Command),SW_HIDE);
      Sleep(1000);
      Memo1.Lines.LoadFromFile('temp.txt');
      tempResult:=Memo1.Lines[Memo1.Lines.Count-1];
      Memo1.Lines.Clear;
      if tempResult='Host not found.' then Result:='Error!'
      else
        begin
          tempResult:=Copy(tempResult,15,17);
          Result:=ReplaceText(tempResult,'-','');
        end;
    end;
      

  5.   

    //远程开机函数
    procedure TFunc.PowerMachine(aMac: String;NMUDP1:TNMUDP);
    var Str:Array[1..102] of char;
        i:Integer;
      function StrtoHex(S:String):Byte;
       begin
         Result := 0;
        Case S[2] of
         '0': Result := 0;
         '1': Result := 1;
         '2': Result := 2;
         '3': Result := 3;
         '4': Result := 4;
         '5': Result := 5;
         '6': Result := 6;
         '7': Result := 7;
         '8': Result := 8;
         '9': Result := 9;
         'A': Result := 10;
         'B': Result := 11;
         'C': Result := 12;
         'D': Result := 13;
         'E': Result := 14;
         'F': Result := 15;
         end;
        Case S[1] of
         '0': Result := Result;
         '1': Result := Result + 16*1;
         '2': Result := Result + 16*2;
         '3': Result := Result + 16*3;
         '4': Result := Result + 16*4;
         '5': Result := Result + 16*5;
         '6': Result := Result + 16*6;
         '7': Result := Result + 16*7;
         '8': Result := Result + 16*8;
         '9': Result := Result + 16*9;
         'A': Result := Result + 16*10;
         'B': Result := Result + 16*11;
         'C': Result := Result + 16*12;
         'D': Result := Result + 16*13;
         'E': Result := Result + 16*14;
         'F': Result := Result + 16*15;
         end;
      end;
    begin
      for i := 1 to 6 do  Str[i] := #255;
      i := 7;
      while i < 103 do
        begin
          Str[i]   := chr(StrToHex(Copy(aMac,1,2)));
          Str[i+1] := chr(StrToHex(Copy(aMac,3,2)));
          Str[i+2] := chr(StrToHex(Copy(aMac,5,2)));
          Str[i+3] := chr(StrToHex(Copy(aMac,7,2)));
          Str[i+4] := chr(StrToHex(Copy(aMac,9,2)));
          Str[i+5] := chr(StrToHex(Copy(aMac,11,2)));
          inc(i,6);
         end;
      NMUDP1.LocalPort := 6666;
      NMUDP1.RemotePort := 6666;
      NMUDP1.RemoteHost:=GetRadiateIP;
      NMUDP1.ReportLevel := 1;
      NMUDP1.SendBuffer(Str,102);
    end;