2012-08-28 59 views
2

我正在尋找一種方法來檢索計算機的IP子網掩碼,我目前在運行時在Delphi上運行 。在德爾福識別計算機的子網掩碼

是否有代碼的方式來檢索子網掩碼並存儲它,以便我可以在其他操作中使用它?

謝謝

+3

請問您的應用程序的目標也與機器Windows 2K的?如果沒有,那麼我可以嘗試使用['GetAdaptersAddresses'](http://msdn.microsoft.com/zh-cn/library/windows/desktop/aa365915(v = vs.85).aspx)函數相反(在RRUZ喚醒WMI解決方案之前:-) – TLama

+1

是的,請使用GetAdaptersAddresses示例。我們使用XP及以上版本。 –

+0

當我通過全新的標題翻譯讓Delphi的GetAdaptersAddresses工作時,我發現了一個MS驚喜 - 如何從這個大結構中獲得IP掩碼。看看['這個線程'](http://comp.newsgroups.archived.at/os.ms-windows.programmer.win32/200908/09081149950.html)部分感受到我目前的脾氣。我可以在這裏發佈它,但我真的不知道是否有一種方法可以獲得與上面的系統支持的'ConvertLengthToIpv4Mask'不同的方法。在所有情況下,我會回顧我已經發布的內容。我越來越覺得,WMI將是最簡單的方法。 – TLama

回答

5

您可以使用Win32_NetworkAdapterConfiguration WMI類和IPSubnet屬性。

試試這個示例代碼

{$APPTYPE CONSOLE} 


uses 
    SysUtils, 
    ActiveX, 
    ComObj, 
    Variants; 

function VarArrayToStr(const vArray: variant): string; 

    function _VarToStr(const V: variant): string; 
    var 
    Vt: integer; 
    begin 
    Vt := VarType(V); 
     case Vt of 
      varSmallint, 
      varInteger : Result := IntToStr(integer(V)); 
      varSingle, 
      varDouble, 
      varCurrency : Result := FloatToStr(Double(V)); 
      varDate  : Result := VarToStr(V); 
      varOleStr : Result := WideString(V); 
      varBoolean : Result := VarToStr(V); 
      varVariant : Result := VarToStr(Variant(V)); 
      varByte  : Result := char(byte(V)); 
      varString : Result := String(V); 
      varArray : Result := VarArrayToStr(Variant(V)); 
     end; 
    end; 

var 
i : integer; 
begin 
    Result := '['; 
    if (VarType(vArray) and VarArray)=0 then 
     Result := _VarToStr(vArray) 
    else 
    for i := VarArrayLowBound(vArray, 1) to VarArrayHighBound(vArray, 1) do 
    if i=VarArrayLowBound(vArray, 1) then 
     Result := Result+_VarToStr(vArray[i]) 
    else 
     Result := Result+'|'+_VarToStr(vArray[i]); 

    Result:=Result+']'; 
end; 

procedure GetWin32_NetworkAdapterConfigurationInfo; 
const 
    WbemUser   =''; 
    WbemPassword  =''; 
    WbemComputer  ='localhost'; 
    wbemFlagForwardOnly = $00000020; 
var 
    FSWbemLocator : OLEVariant; 
    FWMIService : OLEVariant; 
    FWbemObjectSet: OLEVariant; 
    FWbemObject : OLEVariant; 
    oEnum   : IEnumvariant; 
    iValue  : LongWord; 
begin; 
    FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); 
    FWMIService := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword); 
    FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_NetworkAdapterConfiguration Where IpEnabled=True','WQL',wbemFlagForwardOnly); 
    oEnum   := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant; 
    while oEnum.Next(1, FWbemObject, iValue) = 0 do 
    begin 
    Writeln(Format('Caption  %s',[String(FWbemObject.Caption)]));// String 
    if not VarIsNull(FWbemObject.DHCPServer) then 
     Writeln(Format('DHCPServer %s',[String(FWbemObject.DHCPServer)]));// String 
    if not VarIsNull(FWbemObject.IPAddress) then 
     Writeln(Format('IPAddress  %s',[VarArrayToStr(FWbemObject.IPAddress)]));// array String 

    if not VarIsNull(FWbemObject.IPSubnet) then 
     Writeln(Format('IPSubnet  %s',[VarArrayToStr(FWbemObject.IPSubnet)]));// array String 

    if not VarIsNull(FWbemObject.MACAddress) then 
     Writeln(Format('MACAddress  %s',[VarArrayToStr(FWbemObject.MACAddress)]));// array String 

    Writeln; 
    FWbemObject:=Unassigned; 
    end; 
end; 


begin 
try 
    CoInitialize(nil); 
    try 
     GetWin32_NetworkAdapterConfigurationInfo; 
    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. 
+1

+1,這肯定比我一直試圖使用的兩種方法更容易。具有所有結構和枚舉的GetAdaptersAddresses約需要190行代碼。對於深度紮根的WMI對手來說,這是一個很好的例子。 – TLama

+0

感謝,看起來不錯 –

+0

編碼器更容易確定,肯定會在運行時更重。 –

0

1)計算機可能opart不同的網/子網。每個網絡適配器通常都有一些。或者甚至有時甚至超過一個。

2)即使物理上你只有一個網卡,ypou也有環回網絡 - 127.x.x.x子網。如果你有一些像Hamachi或Comodo一樣安裝的VPN - 那將會增加一個網絡適配器。連接電話調制解調器時也一樣。與XP兼容模式等虛擬機相同。所以你無論如何將不得不過濾一些標準。

3)您可以使用WMI的FindAdaptor功能登記網卡:http://www.magsys.co.uk/delphi/magwmi.asp 然後您可以閱讀這些適配器的屬性。 還提到了設置IP的函數,可能還有讀取它們的函數。

即使不是,如何讀取屬性顯示在演示中的URL。 要讀取哪些屬性,您可以確定使用任何WMI瀏覽器。 個人而言,我以ks-soft.net的WMI Explorer加上微軟的WMI工具而告終。 您可以像調整SQLite那樣調試WMI請求,然後將它傳遞給WMI包裝並讀取結果。 但是,返回上述設置IP地址功能,其源可能已經包含屬性名稱,只是爲了節省探索。