looking for a MAC address of a physical adapter

后端 未结 2 1191
甜味超标
甜味超标 2021-01-03 00:54

I would like to use a unique identifier to determine whether my application moved to a different computer. The MAC address seems to be suitable for this purpose. The code I

相关标签:
2条回答
  • 2021-01-03 01:14

    Use the Win32_NetworkAdapter class instead. It has the PhysicalAdapter member. The following example should list you the MAC addresses of physical adapters:

    program Program1;
    
    {$APPTYPE CONSOLE}
    
    uses
      SysUtils, ActiveX, ComObj, Variants;
    
    procedure GetWin32_NetworkAdapterInfo;
    const
      WbemUser = '';
      WbemPassword = '';
      WbemComputer = 'localhost';
      wbemFlagForwardOnly = $00000020;
    var
      ElementCount: LongWord;
      FWMIService: OleVariant;
      FWbemObject: OleVariant;
      EnumVariant: IEnumVARIANT;
      FSWbemLocator: OleVariant;
      FWbemObjectSet: OleVariant;
    begin;
      FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
      FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
      FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM Win32_NetworkAdapter WHERE PhysicalAdapter = 1', 'WQL', wbemFlagForwardOnly);
      EnumVariant := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
      while EnumVariant.Next(1, FWbemObject, ElementCount) = 0 do
      begin
        Writeln(Format('MACAddress %s', [VarToStr(FWbemObject.MACAddress)]));
        FWbemObject := Unassigned;
      end;
    end;
    
    begin
      try
        CoInitialize(nil);
        try
          GetWin32_NetworkAdapterInfo;
        finally
          CoUninitialize;
        end;
      except
        on E:EOleException do
          Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
        on E:Exception do
          Writeln(E.Classname, ':', E.Message);
      end;
      Writeln('Press Enter to exit');
      Readln;
    end.
    

    Based on the code generated by the WMI Delphi Code Creator.

    Update:

    You are actually trying to filter out the adapters which belongs to virtual machines, what is not that easy since they are simulated like to be as physical ones (you can even see them in Device Manager as the physical adapters), so you cannot distinguish them e.g.:

    • by the DHCPEnabled member of the Win32_NetworkAdapter class, because even virtual machines might be configured so they get IP address from a DHCP server
    • by the AdapterTypeId member of the Win32_NetworkAdapter class, since there is no special type for virtual adapters
    • by the PhysicalAdapter member of the Win32_NetworkAdapter class, because they are being simulated to be physical

    Additional reading:

    • Find only physical network adapters with WMI Win32_NetworkAdapter class - this article has a good analysis and it might fulfill your needs (I haven't tested it though)

    • How to determine physical network adapter type using WMI - this question is opened at this time and it is actually exactly what you need

    • How to determine MAC Address of the physical network card - there is one idea I like and I would personally stick to when I'd be 100% sure that the root of the PNPDeviceID member
      of the Win32_NetworkAdapter class for hardware adapters cannot start with something different from the PCI\\ (actually the same I was thinking about when I was comparing the data)

    0 讨论(0)
  • 2021-01-03 01:21

    You could also use GetAdaptersAddresses API from the IP Helper library. For a Delphi translation, Magenta Systems IP Helper Component looks good at first glance.

    0 讨论(0)
提交回复
热议问题