请问如何在程序运行的时候设置计算机的ip地址?
编程环境:Win32 SDK.

解决方案 »

  1.   

    下面介绍在NT下利用代码修改主机名称和IP地址的方法,两种方法都是通过修改注册表来达到目的。 修改IP地址: 你所需要修改的注册表主键为 HKEY_LOCAL_MACHINE,所以请确定你的程序有足够权限。 
    查找子键 SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\netcard#,netcard# 通常为"1",但是如果安装了多块网卡名称就会有所不同。 
    得到键"ServiceName"的值。 
    通过刚才得到的"ServiceName"打开相应的键SYSTEM\CurrentControlSet\Services\"ServiceName"\Parameters\TcpIp。 
    设置键"IpAddress"的值以达到改变IP地址的目的,同时需要设置"SubnetMask"键值以改变子网掩码。 
    设置"DefaultGateway"键值改变默认网关地址。 
    重新启动 
    修改主机名称: 你所需要修改的注册表主键为 HKEY_LOCAL_MACHINE 
    打开子键 SYSTEM\CurrentControlSet\Services\TcpIp\Parameters 
    更改键"HostName"的值 
    打开子键 SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName 
    更改键"ComputerName"的值 
    重新启动
      

  2.   

    告诉你个简单的:
        // 自动获取IP
        ShellExecute(this->m_hWnd, "open", "netsh.exe", "interface ip set address 本地连接 dhcp", "", SW_HIDE);
        // 非自动获取
        ShellExecute(this->m_hWnd, "open", "netsh.exe", "interface ip set address 本地连接 static 192.168.0.2 255.255.255.0 192.168.0.1 1", "", SW_HIDE);如果想启动一个ShellExecute,直到它运行结束,用ShellExecuteEx函数,不知道怎么用请再告诉我。
      

  3.   

    多谢各位!!!
    能用winsock的方法吗?
    如果可以,应该怎么用?
      

  4.   

    还有就是我在窗口中添加一个IP Address控件时,窗口就显示不出来。
    我觉得这个问题和控件RichEdit控件的问题一样,应该要加载DLL吧?
    如果是的话,那这个DLL是什么呢?
      

  5.   

    函数ShellExecute()要包含什么头文件?
      

  6.   

    Windows Sockets 2 (Winsock) enables programmers to create advanced Internet, intranet, and other network-capable applications to transmit application data across the wire, independent of the network protocol being used. 
    Winsock是用于数据传输的,与网络管理无关。可以使用ip helper, 
    或修改注册表,并调用DhcpNotifyConfigChange使改动立即生效(该函数未公开,可能还有其他方法可以实现).BOOL DhcpNotifyConfigChange(
        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
      

  7.   

    1、使用通用控件,需在程序开始处作初始化。
    例如在InitInstance处加上
    INITCOMMONCONTROLSEX icc;
    icc.dwICC=ICC_INTERNET_CLASSES;
    icc.dwSize=sizeof(INITCOMMONCONTROLSEX);
    InitCommonControlsEx(&icc);
    2、ShellExecute需shellapi.h和shell32.lib库
    #include <shellapi.h>
    #pragma comment(lib, "shell32.lib")
      

  8.   

    // 非自动获取
        ShellExecute(this->m_hWnd, "open", "netsh.exe", "interface ip set address 本地连接 static 192.168.0.2 255.255.255.0 192.168.0.1 1", "", SW_HIDE);请问对于上面的这个函数,我如何判断它是否把ip 已经设置成功?
    (因为局域网可能会有ip冲突,所以可能会不成功)
      

  9.   

    还有一个问题:
      
     1、使用通用控件,需在程序开始处作初始化。
    例如在InitInstance处加上
    INITCOMMONCONTROLSEX icc;
    icc.dwICC=ICC_INTERNET_CLASSES;
    icc.dwSize=sizeof(INITCOMMONCONTROLSEX);
    InitCommonControlsEx(&icc);编译时说不认识该标志符,是不是要包含什么头文件?
      

  10.   

    #include <commctrl.h>
    #pragma comment(lib, "comctl32.lib")
      

  11.   

    了解,谢谢!!
    我还是不太清楚哪些是通用控件哪些不是?
    RichEdit不是通用控件吗,为什么它的用法会不一样呢?
    Edit Box控件难道不是通用控件吗?
      

  12.   

    ShellExecute(this->m_hWnd, "open", "netsh.exe", "interface ip set address 本地连接 static 192.168.0.2 255.255.255.0 192.168.0.1 1", "", SW_HIDE);该函数可不可以设置DNS服务器?
    还有一个问题:interface ip set address 本地连接 static 192.168.0.2 255.255.255.0 192.168.0.1 这是一条DOS命令把?
      

  13.   

    1、RichEdit是通用控件, 但因其实现的复杂性, 因此单独将其放在一个dll中(richedit.dll),使用时需LoadLibrary("richedit.dll")
    2、Editbox不是通用控件(common controls),而是标准控件(standart controls),属于轻量级控件。
    3、Common Controls包括:Treeview, listview, statusbar, toolbar, tabctrl, rebar, datetimepicker等,具体可查INITCOMMONCONTROLSEX中dwICC的说明
      

  14.   

    我在cmd中测试过,
    netsh>interface ip set address 本地连接 static 192.168.0.2 255.255.255.0 192.168.0.1
    是一条DOS命令。
    请问在程序中如何判定这条命令执行成功?
      

  15.   

    使用ShellExecute只是执行某个现有的程序,并非调用某个API函数来实现。
    netsh.exe是网络管理的一个常用的命令行程序,有多种用法,
    其中: 
    netsh interface ip set address ...: 设置指定接口的IP地址或默认网关;
    netsh interface ip set dns ...:设置DNS服务器模式和地址;
    netsh interface ip set wins ...: 设置WINS服务器模式和地址。
      

  16.   

    1、ShellExecute的功能有限, 只知道是否执行了netsh.exe, 不能确定netsh.exe是否执行成功. 
    2、netsh.exe会将成功与否输出到标准输出(stdout)上, 除非你使用输入输出重定向, 否则得不到返回的信息,毕竟这不是你自己写的程序。
    3、与其使用输入输出重定向,还不如用前面提到的修改注册表或ip helper的方法更为简单。
      

  17.   

    那如何使用ip helper?
    调用DhcpNotifyConfigChange就可以了?
    这个函数可以修改网关和DNS服务器吗?
    如果可以,那需要包含什么头文件吗?
      

  18.   

    1、使用ip helper的AddIPAddress:(该方法不能永久更改ip地址)
    The IP address created by AddIPAddress is not persistent. The address exists only as long as the adapter object exists. Restarting the computer destroys the address, as does manually resetting the network interface card (NIC). Also, certain PnP events may destroy the address.If the IP address in Address already exists on the network, AddIPAddress returns NO_ERROR and the IP address added is 0.0.0.0.For information about the IPAddr and IPMask data types, see Windows Data Types. To convert an IP address between dotted decimal notation and IPAddr format, use the inet_addr and inet_ntoa functions.Example Code 
    The following example retrieves the IP address table, then adds the IP address 192.168.0.27 to the first adapter. The IP address that was added is then deleted.
    // Before calling AddIPAddress we use GetIpAddrTable to get
    // an adapter to which we can add the IP.
    PMIB_IPADDRTABLE pIPAddrTable;
    DWORD dwSize = 0;pIPAddrTable = (MIB_IPADDRTABLE*) malloc( sizeof( MIB_IPADDRTABLE) );// Make an initial call to GetIpAddrTable to get the
    // necessary size into the dwSize variable
    if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
      GlobalFree( pIPAddrTable );
      pIPAddrTable = (MIB_IPADDRTABLE *) malloc ( dwSize );
    }// Make a second call to GetIpAddrTable to get the
    // actual data we want
    if ( (dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 )) == NO_ERROR ) { 
      printf("\tAddress: %ld\n", pIPAddrTable->table[0].dwAddr);
      printf("\tMask:    %ld\n", pIPAddrTable->table[0].dwMask);
      printf("\tIndex:   %ld\n", pIPAddrTable->table[0].dwIndex);
      printf("\tBCast:   %ld\n", pIPAddrTable->table[0].dwBCastAddr);
      printf("\tReasm:   %ld\n", pIPAddrTable->table[0].dwReasmSize);
    }
    else {
      printf("Call to GetIpAddrTable failed.\n");
    }// IP and mask we will be adding
    UINT iaIPAddress;
    UINT imIPMask;iaIPAddress = inet_addr("192.168.0.27");
    imIPMask = inet_addr("255.255.255.0");// Variables where handles to the added IP will be returned
    ULONG NTEContext = 0;
    ULONG NTEInstance = 0;if ( (dwRetVal = AddIPAddress(iaIPAddress, 
      imIPMask, 
      pIPAddrTable->table[0].dwIndex, 
      &NTEContext, 
      &NTEInstance) ) == NO_ERROR) {
      printf("\tIP address added.\n");
    }else {
      printf("Error adding IP address.\n");  LPVOID lpMsgBuf;
      if (FormatMessage( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM | 
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dwRetVal,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL )) {
        printf("\tError: %s", lpMsgBuf);
      }
      LocalFree( lpMsgBuf );
    }// Delete the IP we just added using the NTEContext
    // variable where the handle was returned
    if ((dwRetVal = DeleteIPAddress(NTEContext)) == NO_ERROR) {
      printf("\tIP Address Deleted.\n");
    }
    else {
      printf("\tCall to DeleteIPAddress failed.\n");
    }
      

  19.   

    2、修改注册表的方法:
    (1)先调用ip helper api中的GetAdaptersInfo取得适配器名称;
    (2)用RegOpenKeyEx打开HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TcpIp\Parameters\(适配器名称)
    (3)用RegSetValueEx修改"IPAddress", "SubnetMask"及“DefaultGateway"键值.
    (4)调用DhcpNotifyConfigChange使改动立即生效:
    BOOL rc;
    hDhcpDll=LoadLibrary("dhcpcsvc.dll");
    pfn=(DHCPNOTIFYPROCPROC)GetProcAddress(hDhcpDll, "DhcpNotifyConfigChange");
    if(NULL!=pfn) 
    rc=pfn(NULL, szAdaptorName, TRUE, nIndex, inet_addr(_addr), inet_addr(addr_mask));
      

  20.   

    MSDN中好象没有DhcpNotifyConfigChange这个函数?
      

  21.   

    DhcpNotifyConfigChange是一个未公开的函数,通过跟踪直接修改ip地址时的API调用发现的。
    需要手工加载dhcpcsvc.dll后取出DhcpNotifyConfigChange地址后再执行。目前不知道有什么更好的方法可以不重启计算机而使ip地址修改立即生效。或许使用iphelper的IpRenewAddress可以,不过没试过。替代的方法是先用ip helper的AddIpAddress修改后再修改注册表。