Einzelnen Beitrag anzeigen

Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.617 Beiträge
 

Re: [WMI] Quellcode erklären

  Alt 15. Jan 2005, 08:35
Zitat von Luckie:
Code:
const
  WMI_HOST_COMPUTER = '.';
  WMI_SYSTEM_NAMESPACE = 'root\CIMV2';
  WMI_CLASS_NIC = 'Win32_Process';
  WMI_ATTRIB_CAPTION = 'Name';
  WMI_ATTRIB_PATH = 'ExecutablePath';
  WMI_ATTRIB_PROCID = 'ProcessID';
  WMI_ATTRIB_PARENT_PROCID = 'ParentProcessId';
  WMI_ATTRIB_SESSIONID = 'SessionID';
  WMI_ATTRIB_THREAD_CNT = 'ThreadCount';
  WMI_ATTRIB_PRIORITY = 'Priority';

function WMIEnumProcesses(Handle: THandle): TPIArray;
var
  Locator     : ISWbemLocator;
  Services    : ISWbemServices;
  ObjectDefinition: ISWbemObject;
  ObjectSet   : SWbemObjectSet;
  ObjectInstances: IEnumVariant;
  WMIObject   : ISWbemObject;
  PropertySet : ISWbemPropertySet;
  WMIProperty : ISWbemProperty;

  TempObj     : OleVariant;
  ObjValue    : Cardinal;
  i           : Integer;
resourcestring
  rsWMIError  = 'WMI-Fehler';
begin
  i := 0;
  [color=red]Locator := CoSWbemLocator.Create;[/color]
  try
    try
      [b]// Der ISWbemLocator ist das Objekt, das die Verbindung zum Dienst 'Systemverwaltung' des zu
      // steuernden Host-Rechners aufbaut, und diese Verbindung zurückgibt.
      // ISWbemServices ist das Objekt das die Verbindung repräsentiert.[/b]
      [color=red]Services := Locator.ConnectServer(WMI_HOST_COMPUTER, WMI_SYSTEM_NAMESPACE,
        '', '', '', '', 0, nil);[/color]
      [b]// hier baust Du also eine Verbindung zum localhost auf, und zwar in den WMI-Namespace root/CIMV2
      // (die WMI-Dienste sind in Namespaces kategorisiert) [/b]
      if Services <> nil then
      begin
        [b]// Über die Verbindung (Services) wird ein Default-Object aller Prozesse geholt
        // (= Typ: Win32_Process)[/b]
        [color=red]ObjectDefinition := Services.Get(WMI_CLASS_NIC,
          wbemFlagUseAmendedQualifiers, nil);[/color]
        [b]// Nachdem ein typisiertes WMI-Object (das Default Object) besteht, können über dieses
        // Objekt nun alle Instanzen geholt werden:[/b]
        [color=red]ObjectSet := ObjectDefinition.Instances_(0, nil);[/color]
        [b]// Die instanzen sind ein ObjectSet. Also mehrere Objekte in eines gepackt. Hier muss nun
        // durchenumeriert werden, um die einzelnen Objekte zu bekommen, also brauchen wir einen
        // Enumerator: [/b]
        [color=red]ObjectInstances := (ObjectSet._NewEnum) as IEnumVariant;[/color]
        [b]// und hier holen wir über den Enumerator nun einzeln alle Instanzen:[/b]
        while (ObjectInstances.Next(1, TempObj, ObjValue) = S_OK) do
        begin
          [b]// im TempObj ist nun nach ObjectInstances.Next die gewünschte Instanz verpackt,
          // also Typecasten wir das Objekt (welches ein Interface ist) in den Typ in dem
          // wir es brauchen:[/b]
          [color=red]WMIObject := IUnknown(TempObj) as SWBemObject;[/color]        
          [b]// das WMI-Objekt hat Eigenschaften, die wir uns auch holen:[/b]
          [color=red]PropertySet := WMIObject.Properties_;[/color]

          [b]// auch das PropertySet ist so ein ObjectSet wie oben, wir können hier durchenumerieren
          // oder wie folgt auch über den Namen der Eigenschaften darauf zugreifen:[/b]
          setlength(result, length(result) + 1);
          [color=green]// welche Eigenschaft will ich abfragen[/color]
          WMIProperty := PropertySet.Item(WMI_ATTRIB_CAPTION, 0);
          if not VarIsNull(WMIProperty.Get_Value) then
            [color=green]// Eigenschaft abfragen[/color]
            result[i].Name := WMIProperty.Get_Value;
          WMIProperty := PropertySet.Item(WMI_ATTRIB_PATH, 0);
          if not VarIsNull(WMIProperty.Get_Value) then
            result[i].Path := WMIProperty.Get_Value;
          WMIProperty := PropertySet.Item(WMI_ATTRIB_PROCID, 0);
          if not VarIsNull(WMIProperty.Get_Value) then
            result[i].ProcID := WMIProperty.Get_Value;
          WMIProperty := PropertySet.Item(WMI_ATTRIB_PARENT_PROCID, 0);
          if not VarIsNull(WMIProperty.Get_Value) then
            result[i].ParentProcID := WMIProperty.Get_Value;
          WMIProperty := PropertySet.Item(WMI_ATTRIB_SESSIONID, 0);
          if not VarIsNull(WMIProperty.Get_Value) then
            result[i].SessionID := WMIProperty.Get_Value;
          WMIProperty := PropertySet.Item(WMI_ATTRIB_THREAD_CNT, 0);
          if not VarIsNull(WMIProperty.Get_Value) then
            result[i].ThreadCount := WMIProperty.Get_Value;
          WMIProperty := PropertySet.Item(WMI_ATTRIB_PRIORITY, 0);
          if not VarIsNull(WMIProperty.Get_Value) then
            result[i].Priority := WMIProperty.Get_Value;
          Inc(i);
        end;
      end;
    finally
      Locator := nil;
      Services := nil;
    end;
  except
    on e: Exception do
      Messagebox(Handle, PChar(e.Message), PChar(rsWMIError), MB_ICONSTOP);
  end;
end;
Ich sollte eh mal eine Einführungsveranstaltung in WMI für meinen Ex-Arbeitgeber erstellen und dort vortragen. Ich denke, ich könnte das zu einem Tut ausbauen. Ich bräuchte dafür aber etwas Hilfe, weil meine Zeit eh etwas arg knapp ist.

Im MSDN unter MSDN-Library durchsuchenWMI Scripting API findest Du übrigens auch eine Liste aller Objekte und einer kompletten Referenz: Scripting API Objetcs. Mit deren Hilfe hab ich mich da durch gewühlt. (Da z.B. mal auf den Locator klicken und schauen was der macht.).
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat