就我而言,我想使用注册表值SYSTEM\CurrentControlSet\Control\Session Manager!PendingFileRenameOperations
在重新启动时删除文件。我使用的是 PowerShell。
使用类似或任何其他命令行二进制文件将数据添加到注册表相对容易MoveFile
,但我认为在有本机方法可用时使用第三方工具(甚至 Sysinternals)是一种糟糕的做法。
问题
PendingFileRenameOperations
仅当其中的条目(它是一个 Multistring 对象)以两个 NUL 字符为后缀时才会执行任何操作,在 Regedit 的二进制查看器中显示为.. ..
。通过 PowerShell 正常添加信息不起作用,并且添加二进制数据虽然可能,但由于 PowerShell(当然是 PowerShell 2.0)缺乏提取 Registry MultiString 对象的二进制数据的能力,因此会清除值中的任何现有数据。
问题
是否可以使用 PS2.0 机器上的本机方法来添加PendingFileRenameOperations
以操作系统真正承认它们的方式进入?
答案1
您可以从 Powershell 使用 .NET,例如:
Add-Type @"
using System;
using System.Text;
using System.Runtime.InteropServices;
public class PFRO
{
public enum MoveFileFlags
{
MOVEFILE_REPLACE_EXISTING = 0x00000001,
MOVEFILE_COPY_ALLOWED = 0x00000002,
MOVEFILE_DELAY_UNTIL_REBOOT = 0x00000004,
MOVEFILE_WRITE_THROUGH = 0x00000008,
MOVEFILE_CREATE_HARDLINK = 0x00000010,
MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x00000020
}
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, MoveFileFlags dwFlags);
public static bool MarkFileForDelete (string srcfile)
{
bool brc = false;
brc = MoveFileEx(srcfile, null, MoveFileFlags.MOVEFILE_DELAY_UNTIL_REBOOT);
return brc;
}
}
"@
$FullName = "C:\toolsde.txt"
if([PFRO]::MarkFileForDelete($FullName))
{
write-host $FullName "will be deleted on next boot"
}
else
{
write-host $FullName "will not be deleted on next boot"
}
此外,我相信 PendingFileRenameOperations2 也是 Windows 会话管理器在启动时处理的注册表值。我怀疑您可以将其用于您的目的,而无需触碰 PendingFileRenameOperations。可能值得一试。
答案2
是的。使用以下 PowerShell 代码:
new-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name "PendingFileRenameOperations" -Value $($((Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name PendingFileRenameOperations -ErrorAction SilentlyContinue).PendingFileRenameOperations) + "\??\C:\file.exe`0`0") -type MultiString -Force | Out-Null
我们在这里做的事情:
- 创建一个 MultiString 类型的新项目(
set-itemproperty
无论出于什么原因,使用都不起作用) - 将该注册表值中的数据(如果有)设置为其主值
- 添加正常的
\??\C:\File.exe
,在本例中是\??\
+ 要删除的文件的文件路径 `0`0
在字符串末尾添加两个 NUL 字节(在 PowerShell 中)
这将确保该文件在下次重启时被删除。