Einzelnen Beitrag anzeigen

Jackie1983

Registriert seit: 12. Mär 2007
486 Beiträge
 
#1

WMI Threads 10 Stück fehler 5 ok.

  Alt 4. Sep 2009, 10:50
Servus,

ich habe mir einen Thread gebastelt, der per WMI Daten abfragt und diese an die Main schickt.
Delphi-Quellcode:
var
  wmi : TWMIThread;
begin
  //OnWMIData -> procedure aus der Main
  wmi := TWMIThread.Create(OnWMIData, 'Win32_OperatingSystem', '', '', '');
  //...
Wenn ich jetzt nur 5 Threads aufrufe bekomme ich keinen Fehler.
Wenn ich aber alle 10 Aufrufe bekomme ich die Meldung
Zitat:
Zugriffsverletzung bei Adresse XXX in Modul MeinProgramm.exe. Lesen von Adresse YYYY.
Aber auch nicht immer.
Jetzt vermute ich das bei der WMI Abfrage was falsch läuft.
Das ist die Execute vom Thread
Delphi-Quellcode:
  inherited;

  CoInitialize(nil);
  WMIThreadCS.Enter; //<- global
  try
    wmi := LoadClassInData(fWMIClass, fWMIHost, fWMIUser, fWMIPass);
  finally
    WMIThreadCS.Leave;
  end;

  wmi.WMIClass := fWMIClass;

  try
    WMIThreadCS.Enter;
    if Assigned(fOnWMIData) then
      fOnWMIData(wmi);
  finally
    WMIThreadCS.Leave;
  end;

  for i:=0 to wmi.InstanceCount-1 do
    wmi.Instance[i].Free;

  OleUninitialize;
Und das ist die Methode LoadClassInData
Delphi-Quellcode:
var
  Locator: ISWbemLocator;
  Services: ISWbemServices;
  SObject: ISWbemObject;
  ObjSet: ISWbemObjectSet;
  SProp: ISWbemProperty;
  SPropSet: ISWbemPropertySet;
  Enum,
  propEnum: IEnumVariant;
  Value: Cardinal;
  TempObj: OleVariant;
// SN: string;
  Count : integer;
  sValue : string;
begin
  result.InstanceCount := 0;
  SetLength(result.Instance,0);
  try
    try
      result.Error := '';
      Locator := CoSWbemLocator.Create;
      //Locator.Connect -> muss man die "verbindung" nicht auch wieder schließen?
      Services := Locator.ConnectServer(wmiHost, 'root\cimv2', lUser, lPasswort, '','', 0, nil);
      ObjSet := Services.ExecQuery('SELECT * FROM '+wmiClass+fWhere, 'WQL',wbemFlagReturnImmediately and wbemFlagForwardOnly , nil);
      Enum := (ObjSet._NewEnum) as IEnumVariant;
      while (Enum.Next(1, TempObj, Value) = S_OK) do
      begin
        SObject := IUnknown(tempObj) as ISWBemObject;
        SPropSet := SObject.Properties_; //me
        propEnum := (SPropSet._NewEnum) as IEnumVariant; //me
        SetLength(result.Instance,Length(result.Instance)+1);
        result.InstanceCount := result.InstanceCount +1;
        result.Instance[result.InstanceCount-1] := TStringList.Create;
        while (propEnum.Next(1, tempObj, Value) = S_OK) do //me
        begin
          SProp := IUnknown(tempObj) as SWBemProperty; //me
          if VarIsNull(SProp.Get_Value) then
            sValue := '<empty>'
          else
          case SProp.CIMType of
            wbemCimtypeSint8, wbemCimtypeUint8, wbemCimtypeSint16, wbemCimtypeUint16,
            wbemCimtypeSint32, wbemCimtypeUint32,
            wbemCimtypeSint64:
              if VarIsArray(SProp.Get_Value) then
              begin
                if VarArrayHighBound(SProp.Get_Value, 1) > 0 then
                  for Count := 1 to VarArrayHighBound(SProp.Get_Value, 1) do
                    sValue := sValue + ' ' + IntToStr(SProp.Get_Value[Count]);
              end else
                sValue := IntToStr(SProp.Get_Value);
            wbemCimtypeReal32, wbemCimtypeReal64:
              sValue := FloatToStr(SProp.Get_Value);
            wbemCimtypeBoolean:
              if SProp.Get_Value then
                sValue := 'True'
              else
                sValue := 'False';
            wbemCimtypeString, wbemCimtypeUint64:
              if VarIsArray(SProp.Get_Value) then
              begin
                if VarArrayHighBound(SProp.Get_Value, 1) > 0 then
                  for Count := 1 to VarArrayHighBound(SProp.Get_Value, 1) do
                    sValue := sValue + ' ' + SProp.Get_Value[Count];
              end else
                sValue := SProp.Get_Value;
            wbemCimtypeDatetime:
              sValue := SProp.Get_Value;
            wbemCimtypeReference:
              begin
                sValue := SProp.Get_Value;
              end;
            wbemCimtypeChar16:
              sValue := '<16-bit character>';
            wbemCimtypeObject:
              sValue := '<CIM Object>';
          end; //ende case
          //showmessage(SProp.Name+' '+result);
          result.Instance[result.InstanceCount-1].Add(SProp.Name+'='+sValue);
          sValue := '';
        end;
      end;
    finally
      Locator := nil;
      Services := nil;
    end;
  except // Trap any exceptions (Not having WMI installed will cause one!)
    on exception do
    begin
      result.Error := SysErrorMessage(GetLastError);
      result.InstanceCount := -1;
    end;
  end;
Ein wenig viel code, aber vielleicht kann mir ja einer weiterhelfen.
Gruß
  Mit Zitat antworten Zitat