紫水晶编程技术论坛 - 努力打造成全国最好的编程论坛

 找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 10404|回复: 7

[开源] delphi版不重启改ip、网关、dns

  [复制链接]

16

主题

97

帖子

0

精华

银牌会员

Rank: 3Rank: 3Rank: 3

积分
611
发表于 2010-12-3 20:49:13 | 显示全部楼层 |阅读模式
本帖最后由 9908006 于 2010-12-3 22:42 编辑

翻译自vc
program MASK;
uses
   windows, SysUtils;

const
   MAX_ADAPTER_NAME_LENGTH = 256;
   MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
   MAX_ADAPTER_ADDRESS_LENGTH = 8;
   IPHelper = 'iphlpapi.dll';


type
   USHORT = WORD;
   ULONG = DWORD;
   time_t = Longint;

   IP_ADDRESS_STRING = record
     S: array[0..15] of Char;
  end;

   IP_MASK_STRING = IP_ADDRESS_STRING;
   PIP_MASK_STRING = ^IP_MASK_STRING;

   PIP_ADDR_STRING = ^IP_ADDR_STRING;
   IP_ADDR_STRING = record
     Next: PIP_ADDR_STRING;
     IpAddress: IP_ADDRESS_STRING;
     IpMask: IP_MASK_STRING;
     Context: DWORD;
  end;

   PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO;
   IP_ADAPTER_INFO = record
     Next: PIP_ADAPTER_INFO;
     ComboIndex: DWORD;
     AdapterName: array[0..MAX_ADAPTER_NAME_LENGTH + 3] of Char;
     Description: array[0..MAX_ADAPTER_DESCRIPTION_LENGTH + 3] of Char;
     AddressLength: UINT;
     Address: array[0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE;
     Index: DWORD;
     Type_: UINT;
     DhcpEnabled: UINT;
     CurrentIpAddress: PIP_ADDR_STRING;
     IpAddressList: IP_ADDR_STRING;
     GatewayList: IP_ADDR_STRING;
     DhcpServer: IP_ADDR_STRING;
     HaveWins: BOOL;
     PrimaryWinsServer: IP_ADDR_STRING;
     SecondaryWinsServer: IP_ADDR_STRING;
     LeaseObtained: time_t;
     LeaseExpires: time_t;
  end;

function GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO; var pOutBufLen: ULONG): DWORD; stdcall; external IPHelper;

function StringToWideString(const S: string): WideString;
var
   InputLength, OutputLength: Integer;
begin
   InputLength := Length(S);
   OutputLength := MultiByteToWideChar(CP_ACP, 0, PChar(S), InputLength, nil, 0);
   SetLength(Result, OutputLength);
   MultiByteToWideChar(CP_ACP, 0, PChar(S), InputLength, PWideChar(Result), OutputLength);
end;



function NotifyIPChange(lpszAdapterName: string): bool;
type TDhcpNotifyConfigChange = function(lpwszServerName: PWideChar; // 本地机器为NULL
     lpwszAdapterName: PWideChar; // 适配器名称
     bNewIpAddress: BOOL; // TRUE表示更改IP
     dwIpIndex: DWORD; // 指明第几个IP地址,如果只有该接口只有一个IP地址则为0
     dwIpAddress: DWORD; // IP地址
     dwSubNetMask: DWORD; // 子网掩码
     nDhcpAction: Integer): BOOL; stdcall;
var
   hDhcpDll: dword;
   MyDhcpNotifyConfigChange: TDhcpNotifyConfigChange;
begin
   hDhcpDll := LoadLibrary('dhcpcsvc.dll');
  if hDhcpDll <> 0 then
  begin
     MyDhcpNotifyConfigChange := GetProcAddress(hDhcpDll, 'DhcpNotifyConfigChange');
     MyDhcpNotifyConfigChange(nil, pwidechar(StringToWideString(lpszAdapterName)), FALSE, 0, 0, 0, 0)
  end;
   CloseHandle(hDhcpDll);
end;

function RegIp(lpszAdapterName, pIPAddress, pNetMask, pNetGate, pDNSServer1, pDNSServer2: string): bool;
var
   hkRoot: HKEY;
   mszDNSServer, mszIPAddress, mszNetMask, mszNetGate: string;
   strKeyName: string;
begin
   strKeyName := 'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\' + lpszAdapterName;
   if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, pchar(strKeyName), 0, KEY_WRITE, hkRoot) <> ERROR_SUCCESS)
     then exit;
   mszDNSServer := pDNSServer1 + '
,' + pDNSServer2;
   mszIPAddress := pIPAddress + #0#0;
   mszNetMask := pNetMask + #0#0;
   mszNetGate := pNetGate + #0#0;
   RegSetValueEx(hkRoot, '
IPAddress', 0, REG_MULTI_SZ, pchar(mszIPAddress), length(mszIPAddress));
   RegSetValueEx(hkRoot, '
SubnetMask', 0, REG_MULTI_SZ, pchar(mszNetMask), length(mszNetMask));
   RegSetValueEx(hkRoot, '
DefaultGateway', 0, REG_MULTI_SZ, pchar(mszNetGate), length(mszNetGate));
   RegSetValueEx(hkRoot, '
NameServer', 0, REG_SZ, pchar(mszDNSServer), length(mszDNSServer));
   RegCloseKey(hkRoot);
end;


function GetLanAdapterName: string;
var
   InterfaceInfo, TmpPointer: PIP_ADAPTER_INFO;
   IP: PIP_ADDR_STRING;
   Len: ULONG;
begin
   result := '
';
   if GetAdaptersInfo(nil, Len) = ERROR_BUFFER_OVERFLOW then
   begin
     GetMem(InterfaceInfo, Len);
     try
       if GetAdaptersInfo(InterfaceInfo, Len) = ERROR_SUCCESS then
       begin
         TmpPointer := InterfaceInfo;
         result := TmpPointer.AdapterName;
       end;
     finally
       FreeMem(InterfaceInfo);
     end;
   end;
end;

var
   AdapterName: string;
begin
   AdapterName := GetLanAdapterName;
   RegIp(AdapterName, '192.168.0.5
', '255.255.255.0', 11.10.10.1', 111.111.11.111', '111.111.11.112');
   NotifyIPChange(AdapterName);
end.



854

主题

3481

帖子

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

Rank: 125Rank: 125Rank: 125Rank: 125Rank: 125

积分
36100
发表于 2010-12-30 23:46:44 | 显示全部楼层
如果是C语言版就好了。。。

16

主题

97

帖子

0

精华

银牌会员

Rank: 3Rank: 3Rank: 3

积分
611
 楼主| 发表于 2010-12-31 16:25:13 | 显示全部楼层
如你所愿,有个类似的vc代码
//VC-ConsoleWithApi
#include <windows.h>
#include <string>

#include <iostream>
#pragma comment(lib,"Ws2_32.lib")
using namespace std;
void GetLanAdapterName( char* szLanAdapterName );
BOOL RegIP( LPCTSTR lpszAdapterName, LPCTSTR pIPAddress, LPCTSTR pNetMask, LPCTSTR pNetGate,  LPCTSTR pDNSServer1,  LPCTSTR pDNSServer2 );
BOOL NotifyIPChange( LPCTSTR lpszAdapterName, int nIndex, LPCTSTR pIPAddress, LPCTSTR pNetMask );

int main()
{

   char AdapterName[ MAX_PATH ] ="";

   GetLanAdapterName( AdapterName );

     // MessageBox(0,AdapterName ,"ff",0);
   RegIP( AdapterName, "172.20.10.253","255.255.255.0", "172.20.10.1", "211.136.17.107", "211.136.18.171" );
   
   NotifyIPChange( AdapterName, 0, "172.20.10.253",  "172.20.10.1" );
   

   return 0;
}



//读取注册表取得适配器名称
void GetLanAdapterName(char* szLanAdapterName)
{   
   HKEY hKey, hSubKey, hNdiIntKey;
    if( ::RegOpenKeyEx( HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, KEY_READ, &hKey ) != ERROR_SUCCESS )
        return;
    DWORD dwIndex = 0;
    DWORD dwBufSize = 256;
    DWORD dwDataType;
    char szSubKey[256];
    unsigned char szData[256];
    while( ::RegEnumKeyEx( hKey, dwIndex++, szSubKey, &dwBufSize, NULL, NULL, NULL, NULL ) == ERROR_SUCCESS )
    {        
      if( ::RegOpenKeyEx( hKey, szSubKey, 0, KEY_READ, &hSubKey ) == ERROR_SUCCESS )
        {            
         if( ::RegOpenKeyEx( hSubKey, "Ndi\\Interfaces", 0, KEY_READ, &hNdiIntKey ) == ERROR_SUCCESS )
         {              
            dwBufSize = 256;
                if( ::RegQueryValueEx( hNdiIntKey, "LowerRange", 0, &dwDataType, szData, &dwBufSize ) == ERROR_SUCCESS )
                {
                    if( strcmp( (char*)szData, "ethernet" ) == 0 ) // 判断是不是以太网卡
               {            
                  dwBufSize = 256;
                        if( ::RegQueryValueEx( hSubKey, "DriverDesc", 0, &dwDataType, szData, &dwBufSize ) == ERROR_SUCCESS )
                        {   
                     // szData 中便是适配器详细描述
                     dwBufSize = 256;
                            if( ::RegQueryValueEx( hSubKey, "NetCfgInstanceID", 0, &dwDataType, szData, &dwBufSize ) == ERROR_SUCCESS )
                     {  
                        //szData中便是适配器名称  
                        strcpy( szLanAdapterName, (const char *)szData );
                        break;
                            }
                        }
                    }
               }
                ::RegCloseKey( hNdiIntKey );
            }  
         ::RegCloseKey(hSubKey);
        }  
      dwBufSize = 256;
    }
   /* end of while */   
   
   ::RegCloseKey(hKey);
}


BOOL RegIP( LPCTSTR lpszAdapterName, LPCTSTR pIPAddress, LPCTSTR pNetMask, LPCTSTR pNetGate,  LPCTSTR pDNSServer1,  LPCTSTR pDNSServer2 )
{
   HKEY hKey;
   string strKeyName = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
   strKeyName += lpszAdapterName;
   if( ::RegOpenKeyEx( HKEY_LOCAL_MACHINE, strKeyName.c_str(), 0, KEY_WRITE, &hKey ) != ERROR_SUCCESS )
      return FALSE;

   string DNSServer = pDNSServer1;
   DNSServer += ",";
   DNSServer += pDNSServer2;

   char mszIPAddress[ 100 ];
   char mszNetMask[ 100 ];
   char mszNetGate[ 100 ];
   char mszDNSServer[ 100 ];
   
   
   strncpy( mszIPAddress, pIPAddress, 98 );
   strncpy( mszNetMask, pNetMask, 98 );
   strncpy( mszNetGate, pNetGate, 98 );
   strncpy( mszDNSServer, DNSServer.c_str(), 98 );

   int nIP, nMask, nGate, nDNSServer;

   nIP = strlen( mszIPAddress );
   nMask = strlen( mszNetMask );
   nGate = strlen( mszNetGate );
   nDNSServer = strlen( mszDNSServer );

   *( mszIPAddress + nIP + 1 ) = 0x00; // REG_MULTI_SZ数据需要在后面再加个0
   nIP += 2;

   *( mszNetMask + nMask + 1 ) = 0x00;
   nMask += 2;

   *( mszNetGate + nGate + 1 ) = 0x00;
   nGate += 2;

   *( mszDNSServer + nDNSServer + 1 ) = 0x00;
   nGate += 2;


   ::RegSetValueEx( hKey, "IPAddress", 0, REG_MULTI_SZ, (unsigned char*)mszIPAddress, nIP );
   ::RegSetValueEx( hKey, "SubnetMask", 0, REG_MULTI_SZ, (unsigned char*)mszNetMask, nMask );
   ::RegSetValueEx( hKey, "DefaultGateway", 0, REG_MULTI_SZ, (unsigned char*)mszNetGate, nGate );
   ::RegSetValueEx( hKey, "NameServer", 0, REG_SZ, (unsigned char*)mszDNSServer, nDNSServer );

   ::RegCloseKey(hKey);

   return TRUE;
}



//未公开函数DhcpNotifyConfigChange位于 dhcpcsvc.dll中.
//原型声明
typedef BOOL ( CALLBACK* DHCPNOTIFYPROC) (
      LPWSTR lpwszServerName,      // 本地机器为NULL
      LPWSTR lpwszAdapterName,   // 适配器名称
      BOOL bNewIpAddress,         // TRUE表示更改IP
      DWORD dwIpIndex,         // 指明第几个IP地址,如果只有该接口只有一个IP地址则为0
      DWORD dwIpAddress,         // IP地址
      DWORD dwSubNetMask,         // 子网掩码
      int nDhcpAction            // 对DHCP的操作 0:不修改, 1:启用 DHCP,2:禁用 DHCP
);


BOOL NotifyIPChange( LPCTSTR lpszAdapterName, int nIndex, LPCTSTR pIPAddress, LPCTSTR pNetMask )
{
   BOOL bResult = FALSE;
   HINSTANCE hDhcpDll;
   DHCPNOTIFYPROC pDhcpNotifyProc;
   WCHAR wcAdapterName[256];

   MultiByteToWideChar( CP_ACP, 0, lpszAdapterName, -1, wcAdapterName,256 );

   if( ( hDhcpDll = ::LoadLibrary("dhcpcsvc.dll") ) == NULL )
      return FALSE;

   if( ( pDhcpNotifyProc = (DHCPNOTIFYPROC)::GetProcAddress( hDhcpDll, "DhcpNotifyConfigChange" ) ) != NULL )
      if(  (pDhcpNotifyProc)(NULL, wcAdapterName, TRUE, nIndex, inet_addr(pIPAddress), inet_addr(pNetMask), 0 ) == ERROR_SUCCESS )
         bResult = TRUE;

   ::FreeLibrary(hDhcpDll);
   return bResult;
}

评分

参与人数 1 +100 +100 水晶币 +100 +100 收起 理由
Tesla.Angela + 100 + 100 + 100 + 100 精品文章

查看全部评分

854

主题

3481

帖子

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

Rank: 125Rank: 125Rank: 125Rank: 125Rank: 125

积分
36100
发表于 2010-12-31 23:59:05 | 显示全部楼层
C代码比pascal代码顺眼多了。。。

273

主题

3287

帖子

1

精华

管理员

嗷嗷叫的老马

Rank: 125Rank: 125Rank: 125Rank: 125Rank: 125

积分
17057

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2011-1-1 10:08:13 | 显示全部楼层
......我看着都蛋疼:Q
我就是嗷嗷叫的老马了......

30

主题

723

帖子

0

精华

钻石会员

Rank: 6Rank: 6

积分
2815
发表于 2015-8-18 09:59:42 | 显示全部楼层
精品文章必须顶

0

主题

40

帖子

0

精华

铜牌会员

Rank: 2Rank: 2

积分
42
发表于 2020-8-13 16:44:44 | 显示全部楼层
测试一下,看好用吗

0

主题

1

帖子

0

精华

初来乍到

Rank: 1

积分
11
发表于 2021-11-9 21:05:07 | 显示全部楼层
好帖子,学习了!
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

手机版|Archiver|紫水晶工作室 ( 粤ICP备05020336号 )

GMT+8, 2024-4-20 05:13 , Processed in 0.032942 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表