Results 1 to 11 of 11

Thread: Parameters zetten/uitlezen defraganalysis

  1. #1

    Parameters zetten/uitlezen defraganalysis

    Hi,

    Ik probeer de status van DefragAnalysis terug te krijgen maar krijg alleen error code 11 terug.

    Code:
    const
      wbemFlagForwardOnly = $00000020;
    var
      FSWbemLocator : OLEVariant;
      FWMIService   : OLEVariant;
      FWbemObjectSet: OLEVariant;
      FWbemObject   : OLEVariant;
      oEnum         : IEnumvariant;
      iValue        : LongWord;
      DefragRecommended : Boolean;
      DefragAnalyseOutput : OleVariant;
      ErrorID : integer;
    begin;
      FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
      FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
      FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_Volume Where Name = "C:\\" ','WQL',wbemFlagForwardOnly);
      oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
      if oEnum.Next(1, FWbemObject, iValue) = 0 then
      begin
        ErrorID := FWbemObject.DefragAnalysis(DefragRecommended, DefragAnalyseOutput);
        showmessage(format('Errorid=%d',[ErrorID]));
    
        FWbemObject:=Unassigned;
      end;
    Het lijkt erop dat de parameters niet correct zijn.

    FWbemObject.DefragAnalysis(DefragRecommended, DefragAnalyseOutput);

    Wie kan mij verder helpen?

  2. #2
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Wel, Delphi booleans worden niet gesnapt door iets wat niet Delphi is, zelfs C/C++ types die boolean heten en 0,1 semantics(b.v. GTK) hebben zijn zelden 1 byte. Dus dit kan niet werken. Probeer eens "longbool"

  3. #3
    Dat geeft nog steeds een foutmelding. De parameter DefragAnalyseOutput zal dan waarschijnlijk ook een andere structuur verwachten.

  4. #4
    Quote Originally Posted by mrniceguy View Post
    een foutmelding
    1+1=b

  5. #5
    Quote Originally Posted by mrniceguy View Post
    Dat geeft nog steeds een foutmelding. De parameter DefragAnalyseOutput zal dan waarschijnlijk ook een andere structuur verwachten.
    Waarschijnlijk ja.

    Je draait dit toch wel als admin?
    (Zo niet, de error 11 kun je ook krijgen als je niet als admin draait)

  6. #6
    Ja ik draai het als admin.

  7. #7
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Ik heb zelf ook zitten klooien, maar zit ook vast. Ik zat te denken dat het resultaat geen volume was, dus ik heb de properties gedumped, maar het lijkt wel zo te zijn.

    Sommigen hebben hetzelfde soort problemen, maar de kb waarnaar ze verwijzen(kb 973597) is dodo.

    Enfin, ik post dit maar om wat van mijn wmi helpers te tonen, met name de for..in helper voor ienumvariant. Sad, maar ja, in Corona tijden is alle response nuttig, zullen we maar zeggen :-)

    Delphi Code:
    1. {$mode delphi}
    2.  
    3. uses windows,variants,activex,comobj,classes,sysutils;
    4.  
    5. Type
    6.   TEatenType = {$ifdef fpc} {$ifdef ver3_0}pulong{$else}Ulong{$endif}{$else}longword{$endif};
    7.   oEnumIterator = record
    8.                       mainobj: OleVariant;
    9.                       oEnum  : IEnumvariant;
    10.                       iteritem : olevariant;
    11.                       iterval  : longword;
    12.                       function Enumerate(v :olevariant):oEnumIterator;
    13.                       function getenumerator :oEnumIterator ;
    14.                       function MoveNext:Boolean; // This is where filtering happens
    15.                       property Current:OleVariant read iteritem;
    16.                    end;
    17.  
    18. function  oEnumIterator.getenumerator :oEnumIterator;
    19. begin
    20.  result:=self;
    21. end;
    22.  
    23. function oEnumIterator.Enumerate(v :olevariant):oEnumIterator;
    24. begin
    25.   mainobj:=v;
    26.   oEnum  := IUnknown(mainobj._NewEnum) as IEnumVariant;
    27.   result:=self;
    28. end;
    29.  
    30. function  oEnumIterator.MoveNext:boolean;
    31. begin
    32.   result:=(oEnum.Next(1, iteritem, iterval) = s_ok); // fail then set iteritem to unassigned?
    33. end;
    34.  
    35. function OleVariantToText(aVar:OleVariant):string;
    36. // mostly quickdump for WMI researchpurposes
    37. var
    38.     i : integer;
    39. begin
    40.   Result:='';
    41.   if not VarIsNull(aVar) then
    42.     if VarIsArray(aVar) then
    43.       begin
    44.         result:='{';
    45.         for i :=VarArrayLowBound(aVar,1) to vararrayhighbound(aVar,1)  do
    46.           begin
    47.             if i<>0 then
    48.               result:=result+',';
    49.             result:=result+OleVariantToText(vararrayget(aVar,[i]));
    50.           end;
    51.         result:=result+'}';
    52.       end
    53.     else
    54.       Result:=VarToStr(aVar);
    55. end;
    56.  
    57. function RightPad(const PadString : string ; HowMany : integer): string;
    58. var
    59.    Counter : integer;
    60.    oldlen : integer;
    61.    x : integer;
    62.  
    63. begin
    64.    result:=padstring;
    65.    oldlen:=Length(PadString);
    66.    Counter := HowMany - oldlen;
    67.    if oldlen<howmany then
    68.      setlength(result,howmany);
    69.    for x := 1 to Counter  do
    70.       result[oldlen+x]:=' ';
    71. end;
    72.  
    73. procedure DumpProperties(obj : OleVariant;condense : boolean=true);
    74. var
    75.   objprop  : OLEVariant;
    76.   propiter : oEnumIterator;
    77.   s        : string;
    78. begin
    79.    for objprop in propiter.Enumerate(obj.Properties_) do
    80.       begin
    81.         s:=OleVariantToText(objprop.Value);
    82.         if (s<>'') or not condense then
    83.            Writeln(rightpad(objprop.Name,40),' = ',s);
    84.       end;
    85. end;
    86. {function GetTypeStr(tdesc : TTypeDesc; Context : ActiveX.ITypeinfo):string;
    87. var
    88.   tinfo    : ActiveX.ITypeInfo;
    89.   bstrName : WideString;
    90. begin
    91.    case tdesc.vt of
    92.      VT_PTR   : Result:=GetTypeStr(tdesc.ptdesc^,Context);
    93.      VT_ARRAY : Result:=Format('Array of %s',[GetTypeStr(tdesc.padesc^.tdescElem,Context)]);
    94.      VT_USERDEFINED : begin
    95.                         context.GetRefTypeInfo(tdesc.hreftype, tinfo);
    96.                         tinfo.GetDocumentation(-1, @bstrName, nil, nil, nil);
    97.                         Result:=bstrName;
    98.                       end
    99.    else
    100.      Result:=VarTypeAsText(tdesc.vt);
    101.    end;
    102. }
    103. procedure doit;
    104. const
    105.   wbemFlagForwardOnly = $00000020;
    106. var
    107.   FSWbemLocator : OLEVariant;
    108.   FWMIService   : OLEVariant;
    109.   FWbemObjectSet: OLEVariant;
    110.   FWbemObject   : OLEVariant;
    111.   oenum         : oEnumIterator;
    112.   DefragRecommended : longint;
    113.   DefragAnalyseOutput : OleVariant;
    114.   ErrorID : integer;
    115. begin;
    116.   FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
    117.   FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
    118.   FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_Volume  Where Name = "d:\\"','WQL',wbemFlagForwardOnly);
    119.  
    120.   for FWbemObject in oEnum.Enumerate(FWbemObjectSet) do
    121.   begin
    122.     DumpProperties(FWbemObject,true);
    123.     ErrorID := FWbemObject.DefragAnalysis(DefragRecommended,DefragAnalyseOutput);
    124.     {$ifdef console}writeln{$else}showmessage{$endif}(format('Errorid=%d',[ErrorID]));
    125.   end;
    126. end;
    127.  
    128. begin
    129.   doit;
    130.  {$ifndef fpc}
    131.  if DebugHook=1 then
    132.   {$endif}
    133.    Readln;
    134. end.

  8. #8
    Quote Originally Posted by marcov View Post
    Sommigen hebben hetzelfde soort problemen, maar de kb waarnaar ze verwijzen(kb 973597) is dodo.
    Daar heb je natuurlijk het internet archief voor
    https://web.archive.org/web/20100409....com/kb/973597

    Maar ik denk dat dat niet zoveel zal helpen.

    Op zich zou het wel moeten werken want in Powershell en VBS werkt het (bij mij) wel.

    VBS Code:
    1. Set VolumeList = GetObject("winmgmts:").ExecQuery("Select * from Win32_Volume")
    2.  
    3. For Each objVolume in VolumeList
    4.     errResult = objVolume.DefragAnalysis(blnRecommended, objReport)
    5.     If errResult = 0 then
    6.  
    7.         Wscript.Echo "Used space: " & objReport.UsedSpace
    8.         Wscript.Echo "Volume name: " & objReport.VolumeName
    9.         Wscript.Echo "Volume size: " & objReport.VolumeSize      
    10.         If blnRecommended = True Then
    11.             Wscript.Echo "This volume should be defragged."
    12.         Else
    13.             Wscript.Echo "This volume does not need to be defragged."
    14.         End If
    15.         Wscript.Echo
    16.     Else
    17.         MsgBox errResult
    18.     End If
    19. Next

    Powershell Code:
    1. # get volumes on local system
    2. $v = get-wmiobject win32_volume
    3.  
    4. # Display Number of volumes
    5. "Number of volumes {0}: " -f $v.length
    6.  
    7. # Now get the C:\ volume
    8. $v1=$v | where {$_\3.name -eq "C:\"}
    9.  
    10. # Perform a defrag analysis on the C: drive
    11. "Performing Defrag Analysis"
    12. $dfa = $v1.DefragAnalysis().DefragAnalysis
    13.  
    14. # Display results
    15. "";"Defrag Results - defrag of C:"
    16. "-----------------------------"
    17.  
    18. "Average File Size (KB) : {0} KB" -f ($dfa.AverageFileSize/1kb)
    19. "Average Fragments per File : {0} " -f $dfa.averageFragmentsPerfile
    20. "Average Free Space per Extent : {0} " -f $dfa.AverageFreeSpacePerExtent
    21. "Cluster Size (KB) : {0} " -f ($dfa.clustersize/1KB)
    22. "Excess Folder Fragments : {0} " -f $dfa.ExcessFolderFragments
    23. "File Percent Fragementation : {0} " -f $dfa.FilePercentFragementation
    24. "Fragmented folders : {0} " -f $dfa.FragmentedFolders
    25. "Free Space (GB) : {0} GB" -f ($dfa.FreeSpace/1gb)
    26. "Free Space Percent : {0} " -f $dfa.FreeSpacePercent
    27. "Free Space Percent Fragementation : {0} " -f $dfa.FreeSpacePercentFragementaion
    28. "Largest free Space Extent : {0} " -f $dfa.LargestFreeSpaceExtent
    29. "MFT Percent In Use : {0} " -f $dfa.MFTPercentInUse
    30. "MFT Record count : {0} " -f $dfa.MFTRecordCount
    31. "Page File Size : {0} " -f $dfa.PageFileSize
    32. "Total Excess Fragements : {0} " -f $dfa.TotalExcessFragements
    33. "Total Files : {0} " -f $dfa.TotalFiles
    34. "Total Folders : {0} " -f $dfa.TotalFolders
    35. "Total Fragmented Files : {0} " -f $dfa.TotalFragmentedFiles
    36. "Total Free Space Extents : {0} " -f $dfa.TotalFreeSpaceExtents
    37. "Total MFT Fragments : {0} " -f $dfa.TotalMftFragments
    38. "Total MFT Size : {0} " -f $dfa.TotalMftSize
    39. "Total Page File Fragements : {0} " -f $dfa.TotalPageFileFragements
    40. "Total Percent Fragementation : {0} " -f $dfa.TotalPercentFragementation
    41. "Total Unmovable Files : {0} " -f $dfa.TotalUnmovableFiles
    42. "Used Space (GB) : {0} GB" -f ($dfa.UsedSpace/1gb)
    43. "Volume Name : {0} " -f $dfa.VolumeName
    44. "Volume Size (GB) : {0} GB" -f ($dfa.VolumeSize/1gb)

    VBS Code:
    1. ' This code simulates the 'defrag /a /v' command except it analyzes
    2. ' all fixed disks, not just a specific one.  
    3. ' The Win32_Volume class is new in Windows Server 2003
    4. ' ---------------------------------------------------------------
    5. ' From the book "Windows Server Cookbook" by Robbie Allen
    6. ' ISBN: 0-596-00633-0
    7. ' ---------------------------------------------------------------
    8.  
    9. ' ------ SCRIPT CONFIGURATION ------
    10. strComputer = "."
    11. ' ------ END CONFIGURATION ---------
    12. set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    13. set colVols = objWMI.ExecQuery("Select * from Win32_Volume where DriveType = 3")
    14.  
    15. for each objVol in colVols
    16.     WScript.Echo "Analyzing volume " & objVol.DriveLetter
    17.  
    18.     intRC = objVol.DefragAnalysis(boolDefrag, objRpt)
    19.     if intRC = 0 then
    20.  
    21.         WScript.Echo " Volume size: " & objRpt.VolumeSize      
    22.         WScript.Echo " Cluster size: " & objRpt.ClusterSize
    23.         WScript.Echo " Used space: " & objRpt.UsedSpace
    24.         WScript.Echo " Free space: " & objRpt.FreeSpace
    25.         WScript.Echo " Percent free space: " & objRpt.FreeSpacePercent
    26.         WScript.Echo " Total fragmentation: " & _
    27.                      objRpt.TotalPercentFragmentation
    28.         WScript.Echo " File fragmentation: " & _
    29.                      objRpt.FilePercentFragmentation
    30.         WScript.Echo " Free space fragmentation: " & _
    31.                      objRpt.FreeSpacePercentFragmentation
    32.  
    33.         WScript.Echo " Total files: " & objRpt.TotalFiles
    34.         WScript.Echo " Average file size: " & objRpt.AverageFileSize
    35.         WScript.Echo " Total fragmented files: " & objRpt.TotalFragmentedFiles
    36.         WScript.Echo " Total excess fragments: " & objRpt.TotalExcessFragments
    37.         WScript.Echo " Avg fragments per file: " & _
    38.                      objRpt.AverageFragmentsPerFile
    39.  
    40.         WScript.Echo " Page file size: " & objRpt.PageFileSize
    41.         WScript.Echo " Total page file fragments: " & _
    42.                      objRpt.TotalPageFileFragments
    43.  
    44.         WScript.Echo " Total folders: " & objRpt.TotalFolders
    45.         WScript.Echo " Fragmented folders: " & objRpt.FragmentedFolders
    46.         WScript.Echo " Excess folder fragments: " & _
    47.                      objRpt.ExcessFolderFragments
    48.  
    49.         WScript.Echo " Total MFT size: " & objRpt.TotalMFTSize
    50.         WScript.Echo " MFT record count: " & objRpt.MFTRecordCount
    51.         WScript.Echo " MFT percent in use: " & objRpt.MFTPercentInUse
    52.         WScript.Echo " Total MFT fragments: " & objRpt.TotalMFTFragments
    53.  
    54.         if boolDefrag = True Then
    55.            WScript.Echo "You should defragment this volume."
    56.         else
    57.            WScript.Echo "You do not need to defragment this volume."
    58.         end if
    59.         WScript.Echo
    60.     else
    61.         WScript.Echo "Error during defragmentation analysis: " & intRC
    62.     end if
    63. next

  9. #9
    PS. Geen idee of dit wat uitmaakt maar volgens mij zou de output een tagVariant moeten zijn (uit OLE2?) en niet een OLEVariant. (VT_DISPATCH | VT_BYREF)

    Maar onder FPC is een tagVariant niet "automatable".
    Last edited by rvk; 01-Apr-20 at 00:37.

  10. #10
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Onder Delphi ook "type not allowed in OLE automation call". Een gewone variant werkt ook niet.

  11. #11
    Met WMI creator is een Delphi console project aangemaakt maar die geeft ook dezelfde error code (11).

    Een project in Lazarus geeft een iets beter resultaat.

    Daar kom ik iets verder mee.

    Code:
    procedure  Invoke_Win32_Volume_DefragAnalysis(const WmiPath :WideString);
    const
      WbemUser    ='';
      WbemPassword='';
      WbemComputer='localhost';
    var
      FSWbemLocator   : OLEVariant;
      FWMIService     : OLEVariant;
      FWbemObjectSet  : OLEVariant;
      FOutParams      : OLEVariant;
      sValue          : string;
      i : integer;
    begin
      FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
      FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
      FWbemObjectSet:= FWMIService.Get(WmiPath);
    
      FOutParams:=FWbemObjectSet.DefragAnalysis();
      sValue:= FOutParams;
    
      Writeln(Format('DefragAnalysis        %s',[sValue]));
      
    end;
    
    
    begin
     try
        Invoke_Win32_Volume_DefragAnalysis('Win32_Volume.DeviceID="\\\\?\\Volume{e4ac2e82-48d2-41dd-8bd1-6725e0073329}\\"');
     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.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •