프로그래밍 노트

델파이에서 컴퓨터의 IP어드레스 설정하기와 설정된 IP어드레스 가져오기 본문

델파이

델파이에서 컴퓨터의 IP어드레스 설정하기와 설정된 IP어드레스 가져오기

띠리 2009. 2. 5. 20:20

델파이에서 컴퓨터의 IP어드레스 설정하기와 설정된 IP어드레스 가져오기




uses
  ComObj, ActiveX, UrlMon,    // for Set IP address
  Winsock;                            // for Get IP address



// ======================================================================
// SetIpConfig()
//    WMI로 IP 어드레스, 게이트웨이, 서브넷마스크 설정
// Arguments ...
//    AIpAddress - IP 어드레스 입력이 안되었을 경우는 DHCP로 설정
//    AGateWay   - [생략가] 생략시 GATEWAY 변경 안함
//    SubnetMask - [생략가] 생략시 기본설정 '255.255.255.0'.
// Return Values ...
//    0 Successful completion, no reboot required.
//    1 Successful completion, reboot required.
//   -1 Unknown OLE Error
//   64 Method not supported on this platform.
//   65 Unknown failure.
//   66 Invalid subnet mask.
//   67 An error occurred while processing an instance that was returned.
//   68 Invalid input parameter.
//   69 More than five gateways specified.
//   70 Invalid IP address.
//   71 Invalid gateway IP address.
//   72 An error occurred while accessing the registry for the info.
//   73 Invalid domain name.
//   74 Invalid host name.
//   75 No primary or secondary WINS server defined.
//   76 Invalid file.
//   77 Invalid system path.
//   78 File copy failed.
//   79 Invalid security parameter.
//   80 Unable to configure TCP/IP service.
//   81 Unable to configure DHCP service.
//   82 Unable to renew DHCP lease.
//   83 Unable to release DHCP lease.
//   84 IP not enabled on adapter.
//   85 IPX not enabled on adapter.
//   86 Frame/network number bounds error.
//   87 Invalid frame type.
//   88 Invalid network number.
//   89 Duplicate network number.
//   90 Parameter out of bounds.
//   91 Access denied.
//   92 Out of memory.
//   93 Already exists.
//   94 Path, file, or object not found.
//   95 Unable to notify service.
//   96 Unable to notify DNS service.
//   97 Interface not configurable.
//   98 Not all DHCP leases could be released or renewed.
//  100 DHCP not enabled on adapter.
//
// Memo
//    IP Address,Gateway and Subnet Mask
//    EnableStatic takes array of string as a parameter
//    for the Addresses. You may wish to rewrite this using
//    array of string as parameter for multiple IP Addresses.
//    I only have use for 1 IP address and Gateway in our application
//    but it's nice to be able to expand it for other users.
//
//    종더 자세한 내용은 Win32_NetworkAdapterConfiguration 클래스 참조
//    원소스 링크  http://www.delphi3000.com/articles/article_4392.asp?SK=
// ======================================================================
function SetIpConfig(const AIpAddress : string = '';
                     const AGateWay : string = '';
                     const ASubnetMask : string = '') : integer;
var Retvar : integer;
    oBindObj : IDispatch;
    oNetAdapters,oNetAdapter,
    oIpAddress,oGateWay,
    oWMIService,oSubnetMask : OleVariant;
    i,iValue : longword;
    oEnum : IEnumvariant;
    oCtx : IBindCtx;
    oMk : IMoniker;
    sFileObj : widestring;
begin
  Retvar := 0;
  sFileObj := 'winmgmts:\\.\root\cimv2';

  // Create OLE [IN} Parameters
  oIpAddress := VarArrayCreate([1,1],varOleStr);
  oIpAddress[1] := AIpAddress;
  oGateWay := VarArrayCreate([1,1],varOleStr);
  oGateWay[1] := AGateWay;
  oSubnetMask := VarArrayCreate([1,1],varOleStr);
  if ASubnetMask = '' then
    oSubnetMask[1] := '255.255.255.0'
  else
    oSubnetMask[1] := ASubnetMask;

  // Connect to WMI - Emulate API GetObject()
  OleCheck(CreateBindCtx(0,oCtx));
  OleCheck(MkParseDisplayNameEx(oCtx,PWideChar(sFileObj),i,oMk));
  OleCheck(oMk.BindToObject(oCtx,nil,IUnknown,oBindObj));
  oWMIService := oBindObj;

  oNetAdapters := oWMIService.ExecQuery('Select * from ' +
                                        'Win32_NetworkAdapterConfiguration ' +
                                        'where IPEnabled=TRUE');
  oEnum := IUnknown(oNetAdapters._NewEnum) as IEnumVariant;

  while oEnum.Next(1,oNetAdapter,iValue) = 0 do begin
    try
      // Set by DHCP ? (Gateway and Subnet ignored)
      if (AIpAddress = '') or SameText(AIpAddress,'DHCP') then
        Retvar := oNetAdapter.EnableDHCP
      // Set via STATIC ?
      else begin
        Retvar := oNetAdapter.EnableStatic(oIpAddress,oSubnetMask);
        // Change Gateway ?
        if (Retvar = 0) and (AGateWay <> '') then
          Retvar := oNetAdapter.SetGateways(oGateway);

        // *** This is where we need some sort of ***
        // *** Network Mapped Resource Refresh    ***
      end;
    except
      Retvar := -1;
    end;

    oNetAdapter := Unassigned;
  end;

  oGateWay := Unassigned;
  oSubnetMask := Unassigned;
  oIpAddress := Unassigned;
  oNetAdapters := Unassigned;
  oWMIService := Unassigned;
  Result := Retvar;
end;


// ======================================================================
// SetDnsServers()
//    WMI로 DNS Server 설정
// Arguments ...
//    APrimaryDNS   - 입력된 문자열이 없으면 DNS Server 리스트 지움
//    AAlternateDNS - [생략가]
// Memo
//    Set DNS Servers
//    Instead of Primary and Alternate you may wish
//    to rewrite this using array of string as the
//    parameters as SetDNSServerSearchOrder will take
//    a list of many DNS addresses. I only have use for
//    Primary and Alternate.
// ======================================================================
function SetDnsServers(const APrimaryDNS : string;
                       const AAlternateDNS : string = '') : integer;
var Retvar : integer;
    oBindObj : IDispatch;
    oNetAdapters,oNetAdapter,
    oDnsAddr,oWMIService : OleVariant;
    i,iValue,iSize : longword;
    oEnum : IEnumvariant;
    oCtx : IBindCtx;
    oMk : IMoniker;
    sFileObj : widestring;
begin
  Retvar := 0;
  sFileObj := 'winmgmts:\\.\root\cimv2';
  iSize := 0;
  if APrimaryDNS <> '' then inc(iSize);
  if AAlternateDNS <> '' then inc(iSize);

  // Create OLE [IN} Parameters
  if iSize > 0 then begin
   oDnsAddr := VarArrayCreate([1,iSize],varOleStr);
   oDnsAddr[1] := APrimaryDNS;
   if iSize > 1 then oDnsAddr[2] := AAlternateDNS;
  end;

  // Connect to WMI - Emulate API GetObject()
  OleCheck(CreateBindCtx(0,oCtx));
  OleCheck(MkParseDisplayNameEx(oCtx,PWideChar(sFileObj),i,oMk));
  OleCheck(oMk.BindToObject(oCtx,nil,IUnknown,oBindObj));
  oWMIService := oBindObj;

  oNetAdapters := oWMIService.ExecQuery('Select * from ' +
                                        'Win32_NetworkAdapterConfiguration ' +
                                        'where IPEnabled=TRUE');
  oEnum := IUnknown(oNetAdapters._NewEnum) as IEnumVariant;

  while oEnum.Next(1,oNetAdapter,iValue) = 0 do begin
    try
      if iSize > 0 then
        Retvar := oNetAdapter.SetDNSServerSearchOrder(oDnsAddr)
      else
        Retvar := oNetAdapter.SetDNSServerSearchOrder();
    except
      Retvar := -1;
    end;

    oNetAdapter := Unassigned;
  end;

  oDnsAddr := Unassigned;
  oNetAdapters := Unassigned;
  oWMIService := Unassigned;
  Result := Retvar;
end;

// ======================================================================
// GetIPFromHost()
//    설정IP 얻기
// Arguments ...
//    HostName - 호스트명
//    IPaddr   - IP 어드레스
//    WSAErr   - WSA에러
// 원소스 링크 : http://delphi.about.com/od/networking/l/aa103100a.htm
// ======================================================================
function GetIPFromHost(var HostName, IPaddr, WSAErr: string): Boolean;
type
  Name = array[0..100] of Char;
  PName = ^Name;
var
  HEnt: pHostEnt;
  HName: PName;
  WSAData: TWSAData;
  i: Integer;
begin
  Result := False;    
  if WSAStartup($0101, WSAData) <> 0 then begin
    WSAErr := 'Winsock is not responding."';
    Exit;
  end;
  IPaddr := '';
  New(HName);
  if GetHostName(HName^, SizeOf(Name)) = 0 then
  begin
    HostName := StrPas(HName^);
    HEnt := GetHostByName(HName^);
    for i := 0 to HEnt^.h_length - 1 do
     IPaddr :=
      Concat(IPaddr,
      IntToStr(Ord(HEnt^.h_addr_list^[i])) + '.');
    SetLength(IPaddr, Length(IPaddr) - 1);
    Result := True;
  end
  else begin
   case WSAGetLastError of
    WSANOTINITIALISED:WSAErr:='WSANotInitialised';
    WSAENETDOWN      :WSAErr:='WSAENetDown';
    WSAEINPROGRESS   :WSAErr:='WSAEInProgress';
   end;
  end;
  Dispose(HName);
  WSACleanup;
end;

procedure TfrmMain.bSetIpClick(Sender: TObject);
begin
  SetIpConfig(trim(edtIp.Text));
end;

procedure TfrmMain.btnGetIpClick(Sender: TObject);
var
  Host, IP, Err: string;
begin
  if GetIPFromHost(Host, IP, Err) then begin
    edtIp.Text := IP;
    frmMain.Caption := 'My IP [' + Host + ']';
  end
  else
    MessageDlg(Err, mtError, [mbOk], 0);
end;

옛날 같으면 이런거 모르면 어떻게 찾아서 했을까?
인터넷이 발달해서 나 같은 사람도 프로그램 만들면서 살 수 있는 것같다. ^^;;

invalid-file

My IP 샘플 소스

Comments