我在cmd中测试过, netsh>interface ip set address 本地连接 static 192.168.0.2 255.255.255.0 192.168.0.1 是一条DOS命令。 请问在程序中如何判定这条命令执行成功?
使用ShellExecute只是执行某个现有的程序,并非调用某个API函数来实现。 netsh.exe是网络管理的一个常用的命令行程序,有多种用法, 其中: netsh interface ip set address ...: 设置指定接口的IP地址或默认网关; netsh interface ip set dns ...:设置DNS服务器模式和地址; netsh interface ip set wins ...: 设置WINS服务器模式和地址。
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"); }
查找子键 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"的值
重新启动
// 自动获取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函数,不知道怎么用请再告诉我。
能用winsock的方法吗?
如果可以,应该怎么用?
我觉得这个问题和控件RichEdit控件的问题一样,应该要加载DLL吧?
如果是的话,那这个DLL是什么呢?
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
例如在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")
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冲突,所以可能会不成功)
1、使用通用控件,需在程序开始处作初始化。
例如在InitInstance处加上
INITCOMMONCONTROLSEX icc;
icc.dwICC=ICC_INTERNET_CLASSES;
icc.dwSize=sizeof(INITCOMMONCONTROLSEX);
InitCommonControlsEx(&icc);编译时说不认识该标志符,是不是要包含什么头文件?
#pragma comment(lib, "comctl32.lib")
我还是不太清楚哪些是通用控件哪些不是?
RichEdit不是通用控件吗,为什么它的用法会不一样呢?
Edit Box控件难道不是通用控件吗?
还有一个问题:interface ip set address 本地连接 static 192.168.0.2 255.255.255.0 192.168.0.1 这是一条DOS命令把?
2、Editbox不是通用控件(common controls),而是标准控件(standart controls),属于轻量级控件。
3、Common Controls包括:Treeview, listview, statusbar, toolbar, tabctrl, rebar, datetimepicker等,具体可查INITCOMMONCONTROLSEX中dwICC的说明
netsh>interface ip set address 本地连接 static 192.168.0.2 255.255.255.0 192.168.0.1
是一条DOS命令。
请问在程序中如何判定这条命令执行成功?
netsh.exe是网络管理的一个常用的命令行程序,有多种用法,
其中:
netsh interface ip set address ...: 设置指定接口的IP地址或默认网关;
netsh interface ip set dns ...:设置DNS服务器模式和地址;
netsh interface ip set wins ...: 设置WINS服务器模式和地址。
2、netsh.exe会将成功与否输出到标准输出(stdout)上, 除非你使用输入输出重定向, 否则得不到返回的信息,毕竟这不是你自己写的程序。
3、与其使用输入输出重定向,还不如用前面提到的修改注册表或ip helper的方法更为简单。
调用DhcpNotifyConfigChange就可以了?
这个函数可以修改网关和DNS服务器吗?
如果可以,那需要包含什么头文件吗?
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");
}
(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));
需要手工加载dhcpcsvc.dll后取出DhcpNotifyConfigChange地址后再执行。目前不知道有什么更好的方法可以不重启计算机而使ip地址修改立即生效。或许使用iphelper的IpRenewAddress可以,不过没试过。替代的方法是先用ip helper的AddIpAddress修改后再修改注册表。