Delphi 如何连接到NIC卡或网络适配器(知道其IP地址)?

Delphi 如何连接到NIC卡或网络适配器(知道其IP地址)?,delphi,network-programming,ip-address,windows-10,Delphi,Network Programming,Ip Address,Windows 10,假设我的系统上有两个NIC或适配器卡,并且我通过以下代码找到了它们的IP地址: procedure TForm4.RetrieveLocalAdapterInformation(strings: Tmemo); var pAdapterInfo, pTempAdapterInfo: PIP_ADAPTER_INFO; AdapterInfo: IP_ADAPTER_INFO; BufLen: DWORD; Status: DWORD; strMAC: String;

假设我的系统上有两个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;

听起来好像您使用的库需要提升权限。在Windows10中,关于UAC没有任何重大变化。如果您的程序正在运行,它将成功。如果不升高,则会失败。因此,您的问题似乎是无法执行提升

由于您的程序需要提升,请确保您实现了这一点。将requireAdministrator选项添加到应用程序清单中


您请求对HKLM的写访问权限,而标准用户将不被授予该权限。调用OpenKeyReadOnly而不是OpenKey。当你只在读的时候,请求写访问是没有意义的

代码的哪个部分导致访问被拒绝?pEnum:=NetSharingManager1.EnumEveryConnection.\u NewEnum as IEnumVariant;您说,如果您的应用程序是以管理员身份执行的,那么这是可行的,但以管理员身份运行程序会导致它在后台运行。正当所以我的问题是,作为一名管理员,您如何启动您的程序?是否通过在windows资源管理器中的“内容”菜单上单击鼠标右键来完成此操作?如果是,您是否尝试过在清单文件的帮助下请求权限提升?当您在资源管理器中选择以管理员身份运行时,Windows 10可能改变了应用程序的启动方式。@SilverWarior是。如果我在exe文件上单击鼠标右键,并通过上下文菜单中的“以管理员身份运行”选项启动该文件,则该文件运行时不会出现任何问题,也不会弹出错误消息。如果我使用“以最高权限运行程序”选项以任何其他方式运行我的程序,它会弹出“拒绝访问”消息框。在Windows 10上,实际错误消息是使用“确定”按钮拒绝访问。TNetSharingManager允许您的程序访问系统的网络层。换言之,您可以对请求进行编程,列出系统上所有可用的网络连接及其属性,启用或禁用它们,等等。MCVE?好的。。。这对我来说是新的。我猜我的程序以前使用过默认值或构建过清单。所以,直到现在我什么都不用做。当我使用链接到项目文件的自定义清单编译我的程序时,它会将其应用于我的程序的exe文件。如果我在另一台机器上运行我的程序,我是否需要随这些rc、res或清单xml文件一起交付我的软件?将清单链接到可执行文件,并仅交付可执行文件
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;
pEnum := (NetSharingManager1.EnumEveryConnection._NewEnum as IEnumVariant);