Как получить количество PendingFileRenameOperations? - PullRequest
0 голосов
/ 22 июня 2011

Я хотел бы получить счетчик PendingFileRenameOperations, у меня есть следующий код ниже, но я продолжаю получать счетчик выше, чем фактическое число, установленное в реестре.

Например, с помощью функции ниже Iполучить счет (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: \ Локальные настройки \ Интернет-файлы \ Content.IE5 \ index.dat # 0 # 0

\ ?? \ Z: \ Локальные настройки \Интернет-файлы \ Content.IE5 \ index.dat # 0 # 0

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

\ ?? \ Z: \Локальные настройки \ Temp \ etilqs_av9VVc5fw7Za76J12NTc # 0 # 0

\ ?? \ Z: \ Локальные настройки \ Интернет-файлы \ Content.IE5 # 0 # 0

\ ?? \ Z: \ LocalНастройки \ Интернет-файлы \ Content.IE5 #0 # 0

\ ?? \ Z: \ Локальные настройки \ Интернет-файлы \ Content.IE5 \ index.dat # 0! \ ?? \ z: \ test.fil # 0

\ ?? \ Z: \ Локальные настройки \ Интернет-файлы \ Content.IE5 # 0 # 0

\ ?? \ Z: \ Локальные настройки \ Интернет-файлы \ Content.IE5 \ index.dat # 0! \?? \ X: \ test.fil # 0

\ ?? \ Z: \ Локальные настройки \ Интернет-файлы \ Content.IE5 # 0 # 0

\ ?? \ Z: \Локальные настройки \ Интернет-файлы \ Content.IE5 \ index.dat # 0! \ ?? \ X: \ test.fil # 0

\ ?? \ Z: \ Локальные настройки \ Интернет-файлы \ Content.IE5# 0! \ ?? \ X: \ test.fil # 0 # 0

Строки с двойным нулем в конце - это файлы, которые будут удалены при следующей перезагрузке. Это те, которые я хотел быхотел бы получить количество (кроме самого последнего двойного нуля).Я действительно не уверен, как разобрать это, чтобы получить то, что я ищу.

Было бы так же просто, как просто добавить еще один # 0 в функцию Pos?

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

Ответы [ 2 ]

3 голосов
/ 22 июня 2011

Значение реестра, которое вы читаете, состоит из пар имен. Каждая операция переименования имеет старое имя и новое имя файла.

Обратите внимание, как полученное значение и ожидаемое значение связаны уравнением y = 2x + 1 Компонент 2x объясняется двумя именами для каждой операции. Вы также подсчитываете пустую строку в конце списка, что объясняет компонент + 1 .

0 голосов
/ 06 мая 2016

PendingFileRenameOperations работает в парах линий.

Для простоты рассмотрим строку 1 в источнике и строку 2 пункта назначения.Строка источника начинается с разделителя \??\, а пункт назначения может начинаться с значения !\??\ или NULL.

Строка \??\ всегда присутствует и может переименовываться во что-то (!\??\) или к нулю (NULL значение), который удаляет источник.

Если переименовать файл или папку, то у вас будет что-то вроде этого

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

или этот

! \ ?? \ C: \ IWantTo \ USethePrevious \ FileorForderName \ ToCreateOverRight \ ThisOtherFolFol

При удалении файла или папки:

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