코드가 어디에서나 컴파일되지 않습니다. VCL도 FMX도 아닙니다. 따라서이 문제는 FMX와 전혀 관련이 없습니다. 아마도 이전 버전이 있었지만 코드는 여기에 없었을 것입니다.
@ TLama는 사용 조항이있는 올바른 경로에 있다고 생각합니다. Ole2
이 아닌 ActiveX
단위에서 IEnumVARIANT
이 필요합니다. 에있는 IEnumVARIANT
의 문제점은 해당 GUID
이 누락되었으므로 as
캐스트가 실패 함을 의미합니다. 그리고 IUnknown
은 Ole2
에 평범한 클래스입니다. 그리고 IEnumVARIANT._Next
의 Ole2
은 var
매개 변수에 부호가있는 정수를 사용합니다. 따라서 Ole2
은 나쁜 소식입니다.
또한 에 필요한 Variants
단위가 누락되었습니다.
코드의 버전은 성공적으로 실행 :
{$APPTYPE CONSOLE}
uses
System.Variants,
Winapi.ActiveX,
System.Win.ComObj;
function GetFirstMacAddress : String;
const
wbemFlagForwardOnly = $00000020;
var
FSWbemLocator : OLEVariant;
FWMIService : OLEVariant;
FWbemObjectSet: OLEVariant;
FWbemObject : OLEVariant;
oEnum : IEnumvariant;
iValue : LongWord;
begin
Result := '';
FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
FWMIService := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
FWbemObjectSet:= FWMIService.ExecQuery('SELECT Description,MACAddress FROM Win32_NetworkAdapterConfiguration','WQL',wbemFlagForwardOnly);
oEnum := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
while oEnum.Next(1, FWbemObject, iValue) = 0 do
begin
if not VarIsNull(FWbemObject.MACAddress) then
begin
Result := (FWbemObject.MACAddress);
exit;
end;
FWbemObject:=Unassigned;
end;
end;
begin
CoInitialize(nil);
Writeln(GetFirstMacAddress);
Readln;
end.
이것은 당신이 시작한 곳으로 바로 돌아 아마! FMX 코드에서 ActiveX
을 사용하고 싶지 않습니다. 하지만 Ole2
도 좋지 않습니다. 코드에 로컬 선언을 IEnumVARIANT
으로 작성하면됩니다. ActiveX
기기 전체를 사용할 필요가 없습니다.
위의 코드부터 시작하십시오. ActiveX
장치를 제거합니다. 그리고 ActiveX
단위의 출처에서 복사 된 IEnumVARAINT
의 좋은 선언을 제공하십시오.
FWIW,이 문제는 WMI에서 해결되지 않습니다. 그것은 매우 무거 우며 현재 진행중인 작업에 필요하지 않습니다. 그것에 대해
{$APPTYPE CONSOLE}
uses
System.SysUtils,
Winapi.Windows,
Winapi.WinSock;
type
TMacAddress = array [0..5] of Byte;
function SendARP(DestIP, SrcIP: ULONG; pMacAddr: Pointer; var PhyAddrLen: ULONG): DWORD; stdcall; external 'Iphlpapi.dll';
procedure InitializeWinSock;
var
wsaData: TWSADATA;
begin
Win32Check(Winapi.WinSock.WSAStartup($0202, wsaData)=0);
end;
procedure FinalizeWinSock;
begin
Winapi.WinSock.WSACleanup;
end;
function inet_addr(const IPAddress: string): ULONG;
begin
Result := ULONG(Winapi.WinSock.inet_addr(PAnsiChar(AnsiString(IPAddress))));
end;
function GetMacAddress(const IPAddress: string): TMacAddress;
var
MaxMacAddrLen: ULONG;
begin
MaxMacAddrLen := SizeOf(Result);
if SendARP(inet_addr(IPAddress), 0, @Result, MaxMacAddrLen)<>NO_ERROR then begin
raise Exception.CreateFmt('Unable to do SendARP on address: ''%s''', [IPAddress]);
end;
end;
var
i: Integer;
mac: TMacAddress;
begin
InitializeWinSock;
mac := GetMacAddress('localhost');
for i := low(mac) to high(mac) do
begin
Write(IntToHex(mac[i], 2));
if i<high(mac) then
Write(':');
end;
Writeln;
FinalizeWinSock;
Readln;
end.
감사, 이전 버전보다 그 심지어 가벼운 무게 : 여기
내가 로컬 네트워크 인터페이스의 MAC 주소를 얻을 것입니다 방법입니다. – John