目前在做一个邮件服务器,采用WINSHOE组件,在实现外发的时候,组件本身只检查首选DNS,没有使用备选DNS(可能有多个)。
   因此现在要修改组件,但不知该怎样取得所有的DNS?
   
   

解决方案 »

  1.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls,Winsock,comobj,comctrls,ActiveX;type
      TForm1 = class(TForm)
        Button1: TButton;
        Memo1: TMemo;
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;const
      IPCFG_DUMMY_FILE = '_dmytmpdns.tmp';
      IPCFG_WIN9X = 'winipcfg.exe /all /batch ';
      IPCFG_WINNT = 'ipconfig.exe /all';
      IPCFG_DNS_SERVER_LINE = 'DNS Servers';
      REG_NT_NAMESERVER_PATH = 'System\CurrentControlSet\Services\Tcpip\Parameters';
      REG_NT_NAMESERVER = 'DhcpNameServer';
      REG_9X_NAMESERVER_PATH = 'System\CurrentControlSet\Services\MSTCP';
      REG_9X_NAMESERVER = 'NameServer';var
      Form1: TForm1;implementation{$R *.dfm}function GetBasicOsType : LongWord;//VER_PLATFORM_WIN32_WINDOWS(Win98)
    var                                //VER_PLATFORM_WIN32_NT(2000 ro XP)
      VerInfo : TOsVersionInfo;
    begin
      VerInfo.dwOSVersionInfoSize := SizeOf(VerInfo);
      GetVersionEx (VerInfo);
      Result := VerInfo.dwPlatformId;
    end;procedure GetConsoleOutput(const CommandLine : string; var Output : TStringList);
    var
      SA: TSecurityAttributes;
      SI: TStartupInfo;
      PI: TProcessInformation;
      StdOutFile, AppProcess, AppThread : THandle;
      RootDir, WorkDir, StdOutFileName: string;
    const
      FUNC_NAME = 'GetConsoleOuput';
    begin
      StdOutFile:=0;
      AppProcess:=0;
      AppThread:=0;
      try
        RootDir:=ExtractFilePath(ParamStr(0));
        WorkDir:=ExtractFilePath(CommandLine);
        if not (FileSearch(ExtractFileName(CommandLine),WorkDir)<>'') then
          WorkDir:=RootDir;
        FillChar(SA,SizeOf(SA),#0);
        SA.nLength:=SizeOf(SA);
        SA.lpSecurityDescriptor:=nil;
        SA.bInheritHandle:=True;
        StdOutFileName:=RootDir+'output.tmp';
        StdOutFile:=CreateFile(PChar(StdOutFileName),
                       GENERIC_READ or GENERIC_WRITE,
                       FILE_SHARE_READ or FILE_SHARE_WRITE,
                       @SA,
                       CREATE_ALWAYS,
                       FILE_ATTRIBUTE_TEMPORARY or
                       FILE_FLAG_WRITE_THROUGH,
                       0);
        if StdOutFile = INVALID_HANDLE_VALUE then
          raise Exception.CreateFmt('Function %s() failed!' + #10#13 +
            'Command line = %s',[FUNC_NAME,CommandLine]);
        FillChar(SI,SizeOf(SI),#0);
        with SI do
          begin
            cb:=SizeOf(SI);
            dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
            wShowWindow:=SW_HIDE;
            hStdInput:=GetStdHandle(STD_INPUT_HANDLE);
            hStdError:=StdOutFile;
            hStdOutput:=StdOutFile;
          end;
        if CreateProcess(nil, PChar(CommandLine), nil, nil,
                         True, 0, nil,
                         PChar(WorkDir), SI, PI) then
           begin
             WaitForSingleObject(PI.hProcess,INFINITE);
             AppProcess:=PI.hProcess;
             AppThread:=PI.hThread;
           end
        else
          raise Exception.CreateFmt('CreateProcess() in function %s() failed!'
                       + #10#13 + 'Command line = %s',[FUNC_NAME,CommandLine]);    CloseHandle(StdOutFile);
        StdOutFile:=0;    Output.Clear;
        Output.LoadFromFile(StdOutFileName);  finally
        if StdOutFile <> 0 then CloseHandle(StdOutFile);
        if AppProcess <> 0 then CloseHandle(AppProcess);
        if AppThread <> 0 then CloseHandle(AppThread);
        if FileExists(StdOutFileName) then
          SysUtils.DeleteFile(StdOutFileName);
      end;
    end;function GetDnsIp : string;
    var
      Output : TStringList;
      DnsIp,
      CmdLine : string;  function BackSlashStr (const s : string) : string;
      begin
        Result := s;
        if Result[Length(Result)] <> '\' then
          Result := Result + '\';
      end;  function GetWindowsPath : string;
      var
        Temp : array [0..MAX_PATH] of char;
      begin
        GetWindowsDirectory (Temp, SizeOf(Temp));
        Result := BackSlashStr (Temp);
      end;  function GetSystemPath : string;
      var
        Temp : array [0..MAX_PATH] of char;
      begin
        GetSystemDirectory (Temp, SizeOf(Temp));
        Result:= BackSlashStr(Temp);
      end;  function LooksLikeIP(StrIn: string): boolean;
      var
        IPAddr : string;
        period, octet, i : Integer;
      begin
        result := false;
        IPAddr := StrIn;
        for i := 1 to 4 do
          begin
            if i = 4 then
              period := 255
            else period := pos('.',IPAddr);
            if period = 0 then
              exit;
            try
              octet := StrToInt(copy(IPAddr,1,period - 1));
            except
              exit;
            end;
            if (octet < (1 div i)) or (octet > 254) then
               exit;
            if i = 4 then
               result := true
            else
               IPAddr := copy(IPAddr,period+1,255);
          end;
      end;
      function GetIpCfg9xOutPath : string;
      begin
        Result := GetWindowsPath + IPCFG_DUMMY_FILE;
      end;  function GetIpCfgExePath : string;
      begin
        Result := '';
        Case GetBasicOsType of
          VER_PLATFORM_WIN32_WINDOWS : Result := GetWindowsPath + IPCFG_WIN9X + GetIpCfg9xOutPath;
          VER_PLATFORM_WIN32_NT      : Result := GetSystemPath + IPCFG_WINNT;
        end;
      end;  function GetDnsIpFromReg : string;
      var
        OpenKey : HKEY;
        Vn,
        SubKey : PChar;
        DataType,
        DataSize : integer;
        Temp : array [0..2048] of char;
      begin
        Result := '';
        SubKey := '';
        Vn := '';
        case GetBasicOsType of
          VER_PLATFORM_WIN32_WINDOWS : begin
                                         SubKey := REG_9X_NAMESERVER_PATH;
                                         Vn := REG_9X_NAMESERVER;
                                       end;
          VER_PLATFORM_WIN32_NT      : begin
                                         SubKey := REG_NT_NAMESERVER_PATH;
                                         Vn := REG_NT_NAMESERVER;
                                       end;
        end;
        if RegOpenKeyEx (HKEY_LOCAL_MACHINE, SubKey, REG_OPTION_NON_VOLATILE,
             KEY_READ, OpenKey) = ERROR_SUCCESS then
          begin
            DataType := REG_SZ;
            DataSize := SizeOf(Temp);
            if RegQueryValueEx (OpenKey, Vn, nil, @DataType, @Temp,
              @DataSize) = ERROR_SUCCESS then
              Result := string(Temp);
            RegCloseKey (OpenKey);
          end;
      end;  function GetDnsIpFromIpCfgOut (const Output : TStringList;
        var DnsIp : string) : boolean;
      var
        i : integer;
        found:boolean;
      begin
        found:=false;
        if Output.Count >= 1 then
          for i := 0 to Output.Count - 1 do
          begin
            if found and LooksLikeIp (trim(Output[i])) then
               begin
                 DnsIp:=DnsIp+#13+trim(Output[i]);
               end
            else
              if Pos(IPCFG_DNS_SERVER_LINE, Output[i]) > 0 then
                 begin
                   DnsIp := Trim(Copy (Output[i], Pos(':', Output[i])+1, Length(Output[i])));
                   Result := LooksLikeIp (DnsIp);
                   found:=true;
                 end;
          end;
      end;
    begin
      CmdLine := GetIpCfgExePath;
      if CmdLine <> '' then
      begin
        Output := TStringList.Create;
        try
          case GetBasicOsType of
            VER_PLATFORM_WIN32_WINDOWS : begin
                                           GetConsoleOutput (CmdLine, Output);
                                           Output.LoadFromFile (GetIpCfg9xOutPath);
                                         end;
                                         else
                                           GetConsoleOutput (CmdLine, Output);
          end;      if GetDnsIpFromIpCfgOut (Output, DnsIp) then
             Result := DnsIp
          else
             Result := GetDnsIpFromReg;
        finally
          Output.Free;
        end;
      end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      memo1.lines.text:=GetDnsIp;
    end;end.
      

  2.   

    真的可以取得多个DNS,谢谢!马上给分!!
    正在进一步学习程序中。
      

  3.   

    我谢谢: lzf1010(luke) 及楼主