如何连接到知道其 IP 地址的 NIC 卡或网络适配器?
how to connect to a NIC card or network adapter knowing its IP address?
假设我的系统上有两个 NIC 或适配器卡,并且我通过以下代码找到了它们的 IP 地址:
procedure TForm4.RetrieveLocalAdapterInformation(strings: Tmemo);
var
pAdapterInfo, pTempAdapterInfo: PIP_ADAPTER_INFO;
AdapterInfo: IP_ADAPTER_INFO;
BufLen: DWORD;
Status: DWORD;
strMAC: String;
i: Integer;
begin
strings.Clear;
BufLen:= sizeof(AdapterInfo);
pAdapterInfo:= @AdapterInfo;
Status:= GetAdaptersInfo(nil, BufLen);
pAdapterInfo:= AllocMem(BufLen);
try
Status:= GetAdaptersInfo(pAdapterInfo, BufLen);
if (Status <> ERROR_SUCCESS) then
begin
case Status of
ERROR_NOT_SUPPORTED:
strings.lines.Add('GetAdaptersInfo is not supported by the operating ' +
'system running on the local computer.');
ERROR_NO_DATA:
strings.lines.Add('No network adapter on the local computer.');
else
strings.Lines.Add('GetAdaptersInfo failed with error #' + IntToStr(Status));
end;
Dispose(pAdapterInfo);
Exit;
end;
while (pAdapterInfo <> nil) do
begin
strings.Lines.Add('Description: ' + pAdapterInfo^.Description);
strings.lines.Add('Name: ' + pAdapterInfo^.AdapterName);
strMAC := '';
for I := 0 to pAdapterInfo^.AddressLength - 1 do
strMAC := strMAC + '-' + IntToHex(pAdapterInfo^.Address[I], 2);
Delete(strMAC, 1, 1);
strings.lines.Add('MAC address: ' + strMAC);
strings.lines.Add('IP address: ' + pAdapterInfo^.IpAddressList.IpAddress.S);
strings.lines.Add('IP subnet mask: ' + pAdapterInfo^.IpAddressList.IpMask.S);
strings.lines.Add('Gateway: ' + pAdapterInfo^.GatewayList.IpAddress.S);
strings.lines.Add('DHCP enabled: ' + IntTOStr(pAdapterInfo^.DhcpEnabled));
strings.lines.Add('DHCP: ' + pAdapterInfo^.DhcpServer.IpAddress.S);
strings.lines.Add('Have WINS: ' + BoolToStr(pAdapterInfo^.HaveWins,True));
strings.lines.Add('Primary WINS: ' + pAdapterInfo^.PrimaryWinsServer.IpAddress.S);
strings.lines.Add('Secondary WINS: ' + pAdapterInfo^.SecondaryWinsServer.IpAddress.S);
pTempAdapterInfo := pAdapterInfo;
pAdapterInfo:= pAdapterInfo^.Next;
if assigned(pAdapterInfo) then Dispose(pTempAdapterInfo);
end;
finally
Dispose(pAdapterInfo);
end;
end;
如何通过特定的 NIC 或网络适配卡连接或引导我的所有网络流量?
我能够在 Windows 7 上使用以下代码完成此操作,但此代码不会 运行 在 Windows 10 上。它会在程序是 运行 作为用户,但不是 运行 作为管理员。但是,作为管理员,我的程序通常不会 运行,而只会作为 Windows 10 上的后台进程....
procedure TDXCommdlg.GetConnectionList(Strings,IdList: TStrings);
var
pEnum: IEnumVariant;
vNetCon: OleVARIANT;
dwRetrieved: Cardinal;
pUser: NETCONLib_TLB.PUserType1;
NetCon : INetConnection;
begin
Strings.Clear;
IdList.Clear;
pEnum := (NetSharingManager1.EnumEveryConnection._NewEnum as IEnumVariant);
while (pEnum.Next(1, vNetCon, dwRetrieved) = S_OK) do
begin
(IUnknown(vNetCon) as INetConnection).GetProperties(pUser);
NetCon := (IUnknown(vNetCon) as INetConnection);
if (pUser.Status in [NCS_CONNECTED,NCS_CONNECTING])//remove if you want disabled NIC cards also
and (pUser.MediaType in [NCM_LAN,NCM_SHAREDACCESSHOST_LAN,NCM_ISDN] )
and (GetMacAddress(GuidToString(pUser.guidId))<>'' ) then
begin
//we only want valid network cards that are enabled
Strings.Add(pUser.pszwName);
IdList.Add(GuidToString(pUser.guidId));
end;
end;
end;
function TDXCommdlg.GetMacAddress(CardID: string): String;
var
Reg: TRegistry;
KeyValues: TSTringList;
i: integer;
CardInstanceID,CardAddress: string;
begin
Result := '';
Reg := TRegistry.Create;
KeyValues := TStringList.Create;
try
Reg.RootKey:=HKEY_LOCAL_MACHINE;
if Reg.OpenKey(MacLocation,false) then
begin
Reg.GetKeyNames(KeyValues);
Reg.CloseKey;
for i := 0 to KeyValues.Count-1 do
if reg.OpenKey(MacLocation+'\'+KeyValues[i],false) then
begin
CardInstanceID := Reg.ReadString('NetCfgInstanceId');
CardAddress := Reg.ReadString('NetworkAddress');
Reg.CloseKey;
if CardInstanceID = CardId then
begin
if CardAddress='' then CardAddress := 'Hardware';
Result := CardAddress;
break;
end;
end;
end;
finally
Reg.Free;
KeyValues.Free;
end;
end;
procedure TDXCommdlg.ResetNIC(const aConnection: string);
var
pEnum: IEnumVariant;
vNetCon: OleVARIANT;
dwRetrieved: Cardinal;
pUser: NETCONLib_TLB.PUserType1;
begin
enabled := false;
try
pEnum := (NetSharingManager1.EnumEveryConnection._NewEnum as IEnumVariant);
while (pEnum.Next(1, vNetCon, dwRetrieved) = S_OK) do
begin
(IUnknown(vNetCon) as INetConnection).GetProperties(pUser);
if pUser.pszwName = aConnection then
begin
(IUnknown(vNetCon) as INetConnection).Disconnect;
(IUnknown(vNetCon) as INetConnection).Connect;
sleep(2000);
break;
end;
end;
finally
enabled := true;
end;
end;
更新
Access Denied 由上面的以下行引发,然后此过程退出。它不会再继续了。
pEnum := (NetSharingManager1.EnumEveryConnection._NewEnum as IEnumVariant);
听起来您使用的库似乎需要提升权限。 Windows 10 关于 UAC 没有任何重大变化。如果您的程序 运行 已提升,它将成功。当它没有提升时它会失败。所以你的问题似乎是你没有执行提升。
由于您的程序需要提升,因此请确保将其体现出来。将 requireAdministrator
选项添加到您的应用程序清单中。
您请求对 HKLM 的写入权限,标准用户不会被授予此权限。调用 OpenKeyReadOnly
而不是 OpenKey
。当您只是阅读时,没有必要要求写权限。
假设我的系统上有两个 NIC 或适配器卡,并且我通过以下代码找到了它们的 IP 地址:
procedure TForm4.RetrieveLocalAdapterInformation(strings: Tmemo);
var
pAdapterInfo, pTempAdapterInfo: PIP_ADAPTER_INFO;
AdapterInfo: IP_ADAPTER_INFO;
BufLen: DWORD;
Status: DWORD;
strMAC: String;
i: Integer;
begin
strings.Clear;
BufLen:= sizeof(AdapterInfo);
pAdapterInfo:= @AdapterInfo;
Status:= GetAdaptersInfo(nil, BufLen);
pAdapterInfo:= AllocMem(BufLen);
try
Status:= GetAdaptersInfo(pAdapterInfo, BufLen);
if (Status <> ERROR_SUCCESS) then
begin
case Status of
ERROR_NOT_SUPPORTED:
strings.lines.Add('GetAdaptersInfo is not supported by the operating ' +
'system running on the local computer.');
ERROR_NO_DATA:
strings.lines.Add('No network adapter on the local computer.');
else
strings.Lines.Add('GetAdaptersInfo failed with error #' + IntToStr(Status));
end;
Dispose(pAdapterInfo);
Exit;
end;
while (pAdapterInfo <> nil) do
begin
strings.Lines.Add('Description: ' + pAdapterInfo^.Description);
strings.lines.Add('Name: ' + pAdapterInfo^.AdapterName);
strMAC := '';
for I := 0 to pAdapterInfo^.AddressLength - 1 do
strMAC := strMAC + '-' + IntToHex(pAdapterInfo^.Address[I], 2);
Delete(strMAC, 1, 1);
strings.lines.Add('MAC address: ' + strMAC);
strings.lines.Add('IP address: ' + pAdapterInfo^.IpAddressList.IpAddress.S);
strings.lines.Add('IP subnet mask: ' + pAdapterInfo^.IpAddressList.IpMask.S);
strings.lines.Add('Gateway: ' + pAdapterInfo^.GatewayList.IpAddress.S);
strings.lines.Add('DHCP enabled: ' + IntTOStr(pAdapterInfo^.DhcpEnabled));
strings.lines.Add('DHCP: ' + pAdapterInfo^.DhcpServer.IpAddress.S);
strings.lines.Add('Have WINS: ' + BoolToStr(pAdapterInfo^.HaveWins,True));
strings.lines.Add('Primary WINS: ' + pAdapterInfo^.PrimaryWinsServer.IpAddress.S);
strings.lines.Add('Secondary WINS: ' + pAdapterInfo^.SecondaryWinsServer.IpAddress.S);
pTempAdapterInfo := pAdapterInfo;
pAdapterInfo:= pAdapterInfo^.Next;
if assigned(pAdapterInfo) then Dispose(pTempAdapterInfo);
end;
finally
Dispose(pAdapterInfo);
end;
end;
如何通过特定的 NIC 或网络适配卡连接或引导我的所有网络流量?
我能够在 Windows 7 上使用以下代码完成此操作,但此代码不会 运行 在 Windows 10 上。它会在程序是 运行 作为用户,但不是 运行 作为管理员。但是,作为管理员,我的程序通常不会 运行,而只会作为 Windows 10 上的后台进程....
procedure TDXCommdlg.GetConnectionList(Strings,IdList: TStrings);
var
pEnum: IEnumVariant;
vNetCon: OleVARIANT;
dwRetrieved: Cardinal;
pUser: NETCONLib_TLB.PUserType1;
NetCon : INetConnection;
begin
Strings.Clear;
IdList.Clear;
pEnum := (NetSharingManager1.EnumEveryConnection._NewEnum as IEnumVariant);
while (pEnum.Next(1, vNetCon, dwRetrieved) = S_OK) do
begin
(IUnknown(vNetCon) as INetConnection).GetProperties(pUser);
NetCon := (IUnknown(vNetCon) as INetConnection);
if (pUser.Status in [NCS_CONNECTED,NCS_CONNECTING])//remove if you want disabled NIC cards also
and (pUser.MediaType in [NCM_LAN,NCM_SHAREDACCESSHOST_LAN,NCM_ISDN] )
and (GetMacAddress(GuidToString(pUser.guidId))<>'' ) then
begin
//we only want valid network cards that are enabled
Strings.Add(pUser.pszwName);
IdList.Add(GuidToString(pUser.guidId));
end;
end;
end;
function TDXCommdlg.GetMacAddress(CardID: string): String;
var
Reg: TRegistry;
KeyValues: TSTringList;
i: integer;
CardInstanceID,CardAddress: string;
begin
Result := '';
Reg := TRegistry.Create;
KeyValues := TStringList.Create;
try
Reg.RootKey:=HKEY_LOCAL_MACHINE;
if Reg.OpenKey(MacLocation,false) then
begin
Reg.GetKeyNames(KeyValues);
Reg.CloseKey;
for i := 0 to KeyValues.Count-1 do
if reg.OpenKey(MacLocation+'\'+KeyValues[i],false) then
begin
CardInstanceID := Reg.ReadString('NetCfgInstanceId');
CardAddress := Reg.ReadString('NetworkAddress');
Reg.CloseKey;
if CardInstanceID = CardId then
begin
if CardAddress='' then CardAddress := 'Hardware';
Result := CardAddress;
break;
end;
end;
end;
finally
Reg.Free;
KeyValues.Free;
end;
end;
procedure TDXCommdlg.ResetNIC(const aConnection: string);
var
pEnum: IEnumVariant;
vNetCon: OleVARIANT;
dwRetrieved: Cardinal;
pUser: NETCONLib_TLB.PUserType1;
begin
enabled := false;
try
pEnum := (NetSharingManager1.EnumEveryConnection._NewEnum as IEnumVariant);
while (pEnum.Next(1, vNetCon, dwRetrieved) = S_OK) do
begin
(IUnknown(vNetCon) as INetConnection).GetProperties(pUser);
if pUser.pszwName = aConnection then
begin
(IUnknown(vNetCon) as INetConnection).Disconnect;
(IUnknown(vNetCon) as INetConnection).Connect;
sleep(2000);
break;
end;
end;
finally
enabled := true;
end;
end;
更新 Access Denied 由上面的以下行引发,然后此过程退出。它不会再继续了。
pEnum := (NetSharingManager1.EnumEveryConnection._NewEnum as IEnumVariant);
听起来您使用的库似乎需要提升权限。 Windows 10 关于 UAC 没有任何重大变化。如果您的程序 运行 已提升,它将成功。当它没有提升时它会失败。所以你的问题似乎是你没有执行提升。
由于您的程序需要提升,因此请确保将其体现出来。将 requireAdministrator
选项添加到您的应用程序清单中。
您请求对 HKLM 的写入权限,标准用户不会被授予此权限。调用 OpenKeyReadOnly
而不是 OpenKey
。当您只是阅读时,没有必要要求写权限。