我想获得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;
答案 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