Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi WMI Ping, aber wie? (https://www.delphipraxis.net/91799-wmi-ping-aber-wie.html)

ddcool 10. Mai 2007 07:17


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

Bernhard Geyer 10. Mai 2007 07:25

Re: WMI Ping, aber wie?
 
Wie schaut der "Referenzcode" in VBS aus und was hast du daraus gemacht?

ddcool 10. Mai 2007 07:52

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:
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;
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.


Grüße

ddcool

Phoenix 10. Mai 2007 08:08

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...

ddcool 10. Mai 2007 08:23

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:
l_WMIObjectSet := l_WMIServices.ExecQuery('SELECT * FROM ' + WMI_CLASS + ' WHERE Address = ''' + PChar(getHostByName(PChar(WMI_SÉRVER)).h_addr) + '''', 'WQL', wbemFlagReturnImmediately, nil);
Aber dabei bekomme ich eine Exception mit Speicherzugriff 00000000 :D (FFFFFFFF wäre besser :D)

Alles sehr komisch.

Oder gibt es die Möglichkeit irgendwo einen Timeout zu setzen????

Phoenix 10. Mai 2007 08:56

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: Win32_PingStatus

Dezipaitor 10. Mai 2007 10:31

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 09:53 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz