怎样用程序修改本机的IP地址?高手请进。

pcman1990 2002-04-29 07:53:29
Windows2000或者WindowsXP环境下,要用程序做到:
(1) 修改本机的IP地址;
(2) 即刻生效,无需重启。

已经尝试过:
(1) 使用IP Hepler APIs。但是,有个问题,注意到AddIPAddress的Remarks:
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.
所以AddIPAddress和DeleteIPAddress不能满足要求。

(2) 如果直接修改注册表,倒是可以完成IP的修改:
a. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards\(Netword Card #),读取ServiceName
b. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\(ServiceName)\Parameters\Tcpip 修改这里TCPIP设置;
c. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Adapters\(ServiceName),读取IpConfig
d. 在IpConfig所示位置(一般是HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Parameters\Interfaces\(ServiceName)),修改那里的TCPIP设置。
但是,修改注册表后,如果用ipconfig看,还是以前的设置,直到重启才生效。感觉好像是要在修改注册表后重新启动某个Service才行,试了一下,没弄出什么结果来。

请各位大虾帮忙看看。谢谢!
...全文
690 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
pcman1990 2002-05-27
  • 打赏
  • 举报
回复
谢谢大家!
先用用netsh对付一下了。结帖。
qsfsea 2002-05-25
  • 打赏
  • 举报
回复
回复人: gameboy999(我心迷茫) ( ) 信誉:100 2001-8-13 13:29:40 得分:38
/******************************************************************************* This is a part of the Microsoft Source Code Samples.
* Copyright 1996 - 1998 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/

/*
Module Name:

ipchange.cpp

Abstract:

This module illustrates how to programmatically change an IP address for
a specific network adapter on your machine. This program also demonstrates how
to retrieve existing network adapter IP configuration information.

IP configurations can be changed for a specific network adapter by using the
AddIpAddress() and DeleteIpAddress() Ip Helper APIs. These APIs require you to
understand adapter index numbers and IP context numbers. In Windows, every network
adapter has a unique index ID and every IP address has a unique context ID.
Adapter index IDs and IP context numbers can be retrieved using the GetAdaptersInfo()
IP Helper API. This program features a list option that displays current network
adapter configuration information by showing all adapters index numbers and IP
address context numbers associated with their corresponding network adaptors.

To execute this application, simply build the application using the Visual C++
Nmake.exe program generation facility. A ipchange.exe program should result.
Execute the ipchange.exe with the following parameters:

Ipchange.exe [ -l ] [ -a -n<index id> -i<ip address> -m<subnet mask> ]
[ -d -c<context id>]

-l List adapter index IDs and IP Address context ID information
-a Add IP Address option
-d Delete IP Address option
-i IP Address to specify with -a option
-m Subnet Mask to specify with -a option
-c IP context ID for an existing IP address
-n Index ID of an existing network adapter

Author:

Jim Ohlund 21-Apr-98

Revision History:

*/

#include <windows.h>
#include <stdio.h>
#include <iphlpapi.h>

void Usage(void) {
printf("Usage: Ipchange [ -l ] [ -a -n<index id> -i<ip address> -m<subnet mask> ] "
"[ -d -c<context id>]\n\n"
"\t -l List adapter index IDs and IP Address context ID information\n"
"\t -a Add IP Address option\n"
"\t -d Delete IP Address option\n"
"\t -i IP Address to specify with -a option\n"
"\t -m Subnet Mask to specify with -a option\n"
"\t -c IP context ID for an existing IP address\n"
"\t -n Index ID of an existing network adapter\n");
}

void main(int argc, char *argv[]) {
ULONG NTEContext = 0;
ULONG NTEInstance;
IPAddr NewIP;
IPAddr NewMask;
DWORD Index;
DWORD Context;
CHAR NewIPStr[64];
CHAR NewMaskStr[64];

PIP_ADAPTER_INFO pAdapterInfo, pAdapt;
PIP_ADDR_STRING pAddrStr;
DWORD AdapterInfoSize;
DWORD Err;
BOOL OptList = FALSE;
BOOL OptAdd = FALSE;
BOOL OptDel = FALSE;

NewIPStr[0] = '\0';
NewMaskStr[0] = '\0';
Context = Index = -1;
for (int i = 1; i < argc; i++)
{
if ((argv[i][0] == '-') || (argv[i][0] == '/'))
{
switch(tolower(argv[i][1]))
{
case 'l':
OptList = TRUE;
break;
case 'a':
OptAdd = TRUE;
break;
case 'c':
if (strlen(argv[i]) > 2)
Context = atoi(&argv[i][2]);
break;
case 'd':
OptDel = TRUE;
break;
case 'i':
if (strlen(argv[i]) > 2)
strcpy(NewIPStr, &argv[i][2]);
break;
case 'm':
if (strlen(argv[i]) > 2)
strcpy(NewMaskStr, &argv[i][2]);
break;
case 'n':
if (strlen(argv[i]) > 2)
Index = atoi(&argv[i][2]);
break;
default:
printf("default\n");
Usage();
return;
}
}
else
{
printf("else\n");
Usage();
return;
}
}

// Check options
if ((OptAdd && (Index == -1 || NewIPStr[0] == '\0' || NewMaskStr[0] == '\0'))
|| (OptDel && Context == -1))
{
Usage();
return;
}

// Get sizing information about all adapters
AdapterInfoSize = 0;
if ((Err = GetAdaptersInfo(NULL, &AdapterInfoSize)) != 0)
{
if (Err != ERROR_BUFFER_OVERFLOW)
{
printf("GetAdaptersInfo sizing failed with error %d\n", Err);
return;
}
}

// Allocate memory from sizing information
if ((pAdapterInfo = (PIP_ADAPTER_INFO) GlobalAlloc(GPTR, AdapterInfoSize)) == NULL)
{
printf("Memory allocation error\n");
return;
}

// Get actual adapter information
if ((Err = GetAdaptersInfo(pAdapterInfo, &AdapterInfoSize)) != 0)
{
printf("GetAdaptersInfo failed with error %d\n", Err);
return;
}

if (OptList)
{
printf("MAC Address - Adapter\n"
"Index Context Ip Address Subnet Mask\n"
"--------------------------------------------------------------\n");

pAdapt = pAdapterInfo;

while (pAdapt)
{
for (UINT i=0; i<pAdapt->AddressLength; i++)
{
if (i == (pAdapt->AddressLength - 1))
printf("%.2X - ",(int)pAdapt->Address[i]);
else
printf("%.2X-",(int)pAdapt->Address[i]);
}
printf("%s\n", pAdapt->Description);

pAddrStr = &(pAdapt->IpAddressList);
while(pAddrStr)
{
printf("%-10.d%-10.d%-20.20s%s\n", pAdapt->Index, pAddrStr->Context, pAddrStr->IpAddress.String, pAddrStr->IpMask.String);
pAddrStr = pAddrStr->Next;
}

pAdapt = pAdapt->Next;
}
}

if (OptAdd)
{
NewIP = inet_addr(NewIPStr);
NewMask = inet_addr(NewMaskStr);
if ((Err = AddIPAddress(NewIP, NewMask, Index, &NTEContext, &NTEInstance)) != 0)
{
printf("AddIPAddress failed with error %d, %d\n", NTEContext, Err);
return;
}
}

if (OptDel)
{
if ((Err = DeleteIPAddress(Context)) != 0)
printf("DeleteIPAddress failed %d\n", Err);
}
}
dyugao 2002-05-25
  • 打赏
  • 举报
回复
标记
kingzai 2002-05-25
  • 打赏
  • 举报
回复
不重启确实比较难。
Solutions:
Connect with a tool like vnc, pc-anywhere, … change the network settings with the control panel. (But a bare bone system does not have a control panel).
Connect with regedt32.exe (or another registry editor) remotely to the Embedded machine and change all the necessary registry entries. (Not a very good solution to use in production and what happens when you want to change something in the field?)
Use IPConfig.exe (which can be found in the NT resource kit but it only handles part of the required functionality)
Write your own program to manipulate the registry remotely.
但是这些方法都要重启
pcman1990 2002-05-25
  • 打赏
  • 举报
回复
谢谢大家!请让我再把该帖保留一段时间。

to videoman():
先谢了!

to swordbroken(断剑书生):
非常感谢!
这样做虽然不是我原先设想的,但也是一种办法。但是要用起来,这里还是有个问题,就是我如何在程序里得到接口名称,即上例中"本地连接"。比如,在英文版的Windows中,其值可能为:"Local Area Connection"。谢谢!
HeavenStar 2002-05-25
  • 打赏
  • 举报
回复
保留!
pcman1990 2002-05-25
  • 打赏
  • 举报
回复
to qsfsea(山重水覆疑无路...)
谢谢!WMI,看上去象,可惜是VB代码,回头研究一下。

to xuying()
谢谢!我试了一下,没有成功。回头到单位的机器上再试试。
xuying 2002-05-25
  • 打赏
  • 举报
回复
1. 用程序修改注册表,使ip地址永久生效
2. 用SetIfEntry()函数将ip所绑定的网卡状态先down,再up就可以不重起机器,使修改后的ip地址生效。

SetIfEntry
Use the SetIfEntry function to set the administrative status of an interface.

DWORD SetIfEntry(
PMIB_IFROW pIfRow // specifies interface and status
);
pfjcsdn 2002-05-25
  • 打赏
  • 举报
回复
关注
qsfsea 2002-05-25
  • 打赏
  • 举报
回复

http://www.csdn.net/expert/topic/265/265672.xml?temp=.5751917

看看对你有没有用!
pcman1990 2002-05-25
  • 打赏
  • 举报
回复
可能还是有问题,我查了一下注册表,没有变化。
总结一下现在的解决方案:
(1) 使用iphelper的API + 手工修改注册表
(2) 使用命令行程序netsh
pcman1990 2002-05-25
  • 打赏
  • 举报
回复
可能还是有问题,我查了一下注册表,没有变化。
总结一下现在的解决方案:
(1) 使用iphelper的API + 手工修改注册表
(2) 使用命令行程序netsh
qsfsea 2002-05-25
  • 打赏
  • 举报
回复
借花献佛而已,不必客气,祝你好运!
pcman1990 2002-05-25
  • 打赏
  • 举报
回复
to qsfsea(山重水覆疑无路...)
谢谢你提供的SourceCode,我刚才试了一下,运行后,从ipconfig中看是没问题的,不过,程序中使用的还是iphelper的API,怀疑重新启动机器后,是不是仍然有效。我这里现在是个人的pc,没法试。等下周到单位里LAN上的机器上试试。总之,非常感谢!
swordbroken 2002-05-24
  • 打赏
  • 举报
回复
以上可以即时生效
swordbroken 2002-05-24
  • 打赏
  • 举报
回复
我有一个挺笨的办法,不过确实有效,我用过。

就是用程序执行一个Dos命令,如下:

netsh interface ip set address "本地连接" static xxx.xxx.xxx.xxx 255.255.255.0

其中“本地连接”就是网上邻居的属性中的连接名,你可以改为自己用的名字

“xxx.xxx.xxx.xxx”为你要设置的IP地址
“255.255.255.0”为子网掩码
videoman 2002-05-24
  • 打赏
  • 举报
回复
见过不重起就修改nt下ip地址的,但好象是汇编的。我看不懂,呵呵。

有机会找到一定发到这个帖子上。
pcman1990 2002-05-05
  • 打赏
  • 举报
回复
pcman1990 2002-04-30
  • 打赏
  • 举报
回复
我几乎把所有的启动的服务都试了一遍,没有结果
pcman1990 2002-04-30
  • 打赏
  • 举报
回复
有人知道吗?
加载更多回复(3)

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧