如何获取PendingFileRenameOperations计数?

时间:2011-06-22 00:51:53

标签: delphi registry delphi-7

我想获得PendingFileRenameOperations的计数,我在下面有以下代码,但是我的计数仍然高于注册表中设置的实际数量。

例如,使用下面的函数,我得到(5)的计数,但只有(2)挂起或我得到(11)的计数,但只有(5)未决。

非常感谢任何帮助。

function GetPendingFileRenameCount(): Integer;
const
  PendingFileRenameOperationsKey = 'SYSTEM\CurrentControlSet\Control\Session Manager';
  PendingFileRenameOperationsName = 'PendingFileRenameOperations';
var
  Reg: TRegistry;
  DataSize: Integer;
  Buffer: string;
begin
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;

    Result := 0;
    if Reg.OpenKeyReadOnly(PendingFileRenameOperationsKey) then
    begin
      DataSize := Reg.GetDataSize(PendingFileRenameOperationsName);
      SetLength(Buffer, DataSize);
      Reg.ReadBinaryData(PendingFileRenameOperationsName, Buffer[1], DataSize);
      while (Pos(#0, Buffer) > 0) do
      begin
        Result := Result + 1;
        Buffer := Copy(Buffer, Pos(#0, Buffer) + 1, Length(Buffer));
      end;
    end;
  finally
    Reg.Free();
  end;
end;

更新

我应该提到我正在尝试删除要删除的待处理文件的数量。

更新两次

以下是我在注册表中的内容:

\ ?? \ Z:\ Local Settings \ Internet Files \ Content.IE5 \ index.dat#0#0

\ ?? \ Z:\ Local Settings \ Internet Files \ Content.IE5 \ index.dat#0#0

\ ?? \ Z:\ Local Settings \ Temp \ etilqs_vTXZjJASQeyi046Mjjig#0#0

\ ?? \ Z:\ Local Settings \ Temp \ etilqs_av9VVc5fw7Za76J12NTc#0#0

\ ?? \ Z:\ Local Settings \ Internet Files \ Content.IE5#0#0

\ ?? \ Z:\ Local Settings \ Internet Files \ Content.IE5#0#0

\ ?? \ Z:\ Local Settings \ Internet Files \ Content.IE5 \ index.dat#0 !\ ?? \ Z:\ test.fil#0

\ ?? \ Z:\ Local Settings \ Internet Files \ Content.IE5#0#0

\ ?? \ Z:\ Local Settings \ Internet Files \ Content.IE5 \ index.dat#0 !\ ?? \ X:\ test.fil#0

\ ?? \ Z:\ Local Settings \ Internet Files \ Content.IE5#0#0

\ ?? \ Z:\ Local Settings \ Internet Files \ Content.IE5 \ index.dat#0 !\ ?? \ X:\ test.fil#0

\ ?? \ Z:\ Local Settings \ Internet Files \ Content.IE5#0 !\ ?? \ X:\ test.fil#0#0

末尾带有双重空值的行是下次重启时将被删除的文件,这些是我想要获取的数量(除了最后一个双重空值)。我真的不确定如何解析这个以获得我正在寻找的东西。

只是在Pos函数中添加另一个#0就这么简单吗?

while (Pos(#0#0, Buffer) > 0) do
begin
  Result := Result + 1;
  Buffer := Copy(Buffer, Pos(#0#0, Buffer) + 1, Length(Buffer));
end;

2 个答案:

答案 0 :(得分:3)

您正在阅读的注册表值包含的名称。每个重命名操作都有旧名称和文件的新名称。

注意你得到的值和你期望的值是如何通过等式 y = 2x + 1 相关联的。 2x 组件由每个操作的两个名称解释。您还要计算列表末尾的空字符串,以便解释 +1 组件。

答案 1 :(得分:0)

PendingFileRenameOperations确实可以成对使用。

为简单起见,我们考虑一下Source中的第1行和Destination中的第2行。 源行以分隔符\??\开头,而目标可能以!\??\NULL值开头。

\??\行始终存在,并且可以重命名为(!\??\)或无重命(NULL值),这会删​​除源。

如果重命名文件或文件夹,那么你会有类似这样的东西

  

\ ?? \ C:\ ThisIs_a \ File_ThatExists \ Somewhere123 \ inheComputer.tmp

或者

  

!\ ?? \ C:\ IWantTo \ USethePrevious \ FileorForderName \ ToCreateOverRight \ ThisOtherFileFolder.dll

如果删除文件或文件夹:

  

\ ?? \ C:\ I_Have_this \ FileOrFolder_that \ Ineed \ toDelete

NULL(注意:在RegEdit中,您只会看到一个空行)

如果查看此键的二进制值,可以看到那里的NULL值,由四个零组成。

根据您用于检索值内数据的脚本语言,它将处理NULL值不同。

我在此脚本中使用PowerShell来检索PendingFileRenameOperations的数据值。我在脚本中添加了注释,试图弄清楚发生了什么。它会计算要删除多少文件的\??\减去!\??\的数量。它还会计算NULL值。当数组中断行时,会添加这些内容。

<!-- language: powershell -->
$RebootPendingPathKey = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
$RebootPendingValueName = "PendingFileRenameOperations" #Value Name

function RegistryQuery ($Path, $Value)
{
  try
  { 
    if(get-itemproperty -path $Path -ErrorAction SilentlyContinue)
    { #Checks if the Key/Path exists,
      return (get-itemproperty -path $Path -ErrorAction SilentlyContinue).$Value
    } #if the path exists, then gets the value of the key
  } catch
  {
    write-host "Error Message from Registry Query $_"
  }
}

function CountOfDeletedReplacedFiles($CombinedKeys)
{
  [array]$CombinedKeysWithAddedNull = @()
  $ReplaceCount = $DeleteCount = $NullCount = 0
  foreach($key in $CombinedKeys)
  {
    #If there is a gap in betweenlines it will be replaced with a Null value
    if(!($key -eq ""))
    {
      #If ! (excalmation mark) is found in the first element of the string then the file will be replaced
      if($key[0] -eq "!")
      {
        #It counts files to be replaced
        $ReplaceCount++
      } else
      {
        #It counts files to be deleted
        $DeleteCount++
      }
      #Adds the original value to the new array
      $CombinedKeysWithAddedNull += $key
    } else
    {
      #Add Null values when there is a space present
      $CombinedKeysWithAddedNull += $NULL
      #Counts Null values added to the CombinedKeysWithAddedNull
      $NullCount++
    }
  }
  #These lines are just for debugging purposes
  write-host "CombinedKeys elements in Incoming Array:"  $CombinedKeys.count
  write-host "CombinedKeysWithAddedNull elements in Array: "  $CombinedKeysWithAddedNull.count
  write-host "Number of Null values added: "  $NullCount
  write-host "Replace File Count: "  $ReplaceCount
  write-host "Delete File Count: "  $DeleteCount
  write-host "Number of Files to be actually deleted: " ($DeleteCount - $ReplaceCount)
  return $CombinedKeysWithAddedNull #Return Array with Nulls in case you need to set this value in a backup key
}
[array]$PendingKey = RegistryQuery $RebootPendingPathKey $RebootPendingValueName
[array]$Merged = CountOfDeletedReplacedFiles $PendingKey