![]() |
WMI Ping, aber wie?
Hallo zusammen,
ich hätte da mal eine Frage. Wie realisiere ich in Delphi einen WMI Ping. Habe mir schon mehrere Beispiele in anderen SPrachen angesehen (VBS) und versucht in Delphi umzusetzen. Funktionieren tut leider garnichts. Das Problem ist einfach das ich auf ca 320 Rechnern jeweils eine WMI Abfrage machen möchte. Wenn ich nun aber keine Berechtigungen auf dem Rechner habe, dauert die Abfrage ewig und das Programm freezed in der Zeit. Umgehen kann ich das ganze nicht, da ich mir die Rechnerliste direkt aus dem Active-Directory sauge. Die anderen Fehler wie nicht erreichbar oder kein Windows habe ich mittels Ping und vorherigem Verbindungsversuch auf Port 135 recht gut in den Griff bekommen. Ich danke dür jede Hilfe. Grüße ddcool |
Re: WMI Ping, aber wie?
Wie schaut der "Referenzcode" in VBS aus und was hast du daraus gemacht?
|
Re: WMI Ping, aber wie?
Hier der Code aus VBS:
Code:
Dim sHost 'name of Windows XP computer from which the PING command will be initiated
Dim sTarget 'name or IP address of remote computer to which connectivity will be tested Dim cPingResults 'collection of instances of Win32_PingStatus class Dim oPingResult 'single instance of Win32_PingStatus class sHost = "SWYNKPC-XP001" sTarget = "192.168.12.14" Set cPingResults = GetObject("winmgmts:{impersonationLevel=impersonate}//" & _ sHost & "/root/cimv2"). ExecQuery("SELECT * FROM Win32_PingStatus " & _ "WHERE Address = '" + sTarget + "'") For Each oPingResult In cPingResults If oPingResult.StatusCode = 0 Then If LCase(sTarget) = oPingResult.ProtocolAddress Then WScript.Echo sTarget & " is responding" Else WScript.Echo sTarget & "(" & oPingResult.ProtocolAddress & ") is responding" End If Wscript.Echo "Bytes = " & vbTab & oPingResult.BufferSize Wscript.Echo "Time (ms) = " & vbTab & oPingResult.ResponseTime Wscript.Echo "TTL (s) = " & vbTab & oPingResult.ResponseTimeToLive Else WScript.Echo sTarget & " is not responding" WScript.Echo "Status code is " & oPingResult.StatusCode End If Next Und hier mein eigener Code:
Delphi-Quellcode:
Achso es hat nichts damit zu tun dass der Statuscode ein Integer im WMI ist. Andere Integer lassen sich mit dieser Funktion auch Problemlos auslesen.
function getWMIValue(WMI_SÉRVER:string;WMI_CLASS:string;WMI_VALUE:string): TStringList;
var l_WMILocator: ISWbemLocator; l_WMIServices: ISWbemServices; l_WMIObjectDefinition: ISWbemObject; l_WMIObjectSet: SWbemObjectSet; l_WMIObjectInstances: IEnumVariant; l_WMIObject: ISWbemObject; l_WMIPropertySet: ISWbemPropertySet; l_WMIProperty: ISWbemProperty; l_TempObj: OleVariant; l_ObjValue: Cardinal; begin result := TStringList.Create; try l_WMILocator := CoSWbemLocator.Create; l_WMIServices := L_WMILocator.ConnectServer(WMI_SÉRVER, 'root\CIMV2', '', '', '', '', 0, nil); l_WMIObjectDefinition := l_WMIServices.Get(WMI_CLASS, wbemFlagUseAmendedQualifiers, nil); l_WMIObjectSet := l_WMIObjectDefinition.Instances_(0, nil); l_WMIObjectInstances := (l_WMIObjectSet._NewEnum) as IEnumVariant; except result.Add(''); Exit; end; while (l_WMIObjectInstances.Next(1, l_TempObj, l_ObjValue) = S_OK) do begin l_WMIObject:= IUnknown(l_TempObj) as SWBemObject; l_WMIPropertySet := l_WMIObject.Properties_; l_WMIProperty := l_WMIPropertySet.Item(WMI_VALUE, 0); if not VarIsNull(l_WMIProperty.Get_Value) then result.Add(l_WMIProperty.Get_Value) else result.Add(''); end; end; procedure TfrmMain.ButtonClick(Sender: TObject); begin if getWMIValue('Testrechner','Win32_PingStatus','StatusCode').Strings[0] = '0' then ShowMessage('Es hat geklappt') else ShowMessage('Bäähh du darfst nicht!'); end; Grüße ddcool |
Re: WMI Ping, aber wie?
Kurz: Geht nicht.
Entweder, der WMI-Connect geht durch (inkl. Berechtigungsprüfung), oder er geht nicht durch (und das dauert nunmal). Einen 'WMI-Ping', um z.B. mal kurz 'anzuconnecten', gibt es nicht. Aber wenn Du die Informationen eh aus dem ActiveDirectory ziehst... dort müsste auf dem Computerkonto doch stehen ob Du als User da Rechte drauf hast oder nicht... |
Re: WMI Ping, aber wie?
Jein es steht zwar im AD welche Gruppe auf das Objekt zugreifen darf aber man kann ja auch lokal auf dem Rechner noch Admingruppen hinzufügen. Dann müsste ich immer mit Domain-Admisn Orüfung arbeiten, bzw ein Domainadmin sein.
WMI-Ping gibt es wohl. Schau doch mal bei Microsoft :D Im VBS Script funktioniert es ja auch, bekomme eine sehr schnelle Antwort, wenn ich Zugriff habe und eine langsamere Antwort (ca 500ms) wenn ich keinen habe. Wenn ich allerdings keinen Zugriff habe und ohne Ping eine Abfrage starte dauert es im VBS und im Delphi ca 5 sec bis er merkt, dass er nicht darf. Rechne mal so 5 sec x 30 (sind unsere Server). Das dauert dann extram lange. habe jetzt eine eventuelle Möglichkeit gefunden. In der getWMIValue Funktion einfach das:
Delphi-Quellcode:
Aber dabei bekomme ich eine Exception mit Speicherzugriff 00000000 :D (FFFFFFFF wäre besser :D)
l_WMIObjectSet := l_WMIServices.ExecQuery('SELECT * FROM ' + WMI_CLASS + ' WHERE Address = ''' + PChar(getHostByName(PChar(WMI_SÉRVER)).h_addr) + '''', 'WQL', wbemFlagReturnImmediately, nil);
Alles sehr komisch. Oder gibt es die Möglichkeit irgendwo einen Timeout zu setzen???? |
Re: WMI Ping, aber wie?
Mit dem WMI-Kommando setzt Du remote einen Stinknormalen Ping an. Das hat nix mit WMI als solchem zu tun. Du könntest anstelle eines Pings genausogut die MAC Adressen abfragen...
GuckstDu MSDN: ![]() |
Re: WMI Ping, aber wie?
Erstell doch ein paar Threads für die Abfragen. Sagen wir 20-30 Threads mit immer einer Abfrage darin.
Dann hast du schön Zeit gespart. Außerdem kannst du dann auch die Anzeige gut darstellen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz