您的代碼無法在任何地方編譯。無論是VCL還是FMX。所以,這個問題根本與FMX無關。也許是早期版本,但不是這裏的代碼。
我認爲@TLama的使用條款是正確的。您需要ActiveX
單元中的IEnumVARIANT
單元,而不是Ole2
中的單元。 Ole2
中IEnumVARIANT
的問題在於它缺少其GUID
,這意味着as
轉換失敗。 Ole2
中的IUnknown
是一個很奇怪的類。 Ole2
中的IEnumVARIANT._Next
對var
參數使用有符號整數,這也很奇怪。所以,Ole2
似乎是壞消息!
此外,您錯過了VarIsNull
所需的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來解決這個問題。這是非常重量級的,只是不需要手頭的任務。
下面我將如何獲得本地網絡接口的MAC地址:
{$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.
感謝的是,它比以前的版本更輕的重量。 – John