我知道有很多类似的问题,但我仍然没有找到答案。
我尝试删除一个文件夹,里面有一些脚本。
文件夹位于:C:\PUBLIC\文件夹中
文件夹里有7个脚本。
脚本CopyFiles.ps1将其中4个文件复制到不同的位置。
复制后,它会删除文件夹本身和所有其他文件。
脚本如下所示:
[string] $Path = "";
[string] $Destination = "";
# Copy the Folder
[string] $Destination = "C:\ProgramData\Path\To\Folder";
[string] $Path = "C:\Public\Folder";
Copy-Item -Path $Path -Destination $Destination
# Copy Files
[string[]] $Files = ("CreateUser.ps1", "RemoveFiles.ps1", "RemoveUser.ps1", "UpdateUser.ps1");
foreach($file in $Files)
{
$Script = $Path + "\" + $file
write-host $Script
Copy-Item -Path $Script -Destination $Destination
}
[string] $Path = "C:\Public";
Remove-Item -Path $Path -Include *UserManager* -Recurse -Force
到目前为止,这个剧本发挥了巨大的作用。但今天不是。我收到以下错误消息:
Remove-Item:无法删除位于‘C:\Public’的项,因为它正在使用中。位于C:\PUBLIC\FORDER\CopyFiles.ps1:24字符:1
这也是完全有意义的,因为它在使用中,它不会被删除。但为什么它能奏效到现在呢?
1条答案
按热度按时间7ivaypg91#
您需要在尝试删除的文件夹之外使用
Set-Location
(cd
)。如果某个文件夹是其当前工作目录,则外壳程序将在该文件夹上拥有一个打开的句柄。您不必从脚本中调用
Set-Location
(尽管您可以),只是不要调用将C:\Public\Folder
设置为工作目录的脚本。如果您不在该文件夹中,则必须确定哪个进程正在锁定该文件夹。我从未以编程方式完成这项工作,但我通常使用的工具是LockHunter。如果您有Chocolatey,您可以使用以下命令轻松安装:
补充阅读
我还没有尝试过这一点,但好奇心终于在这个主题上占据了我的上风,我找到了一个关于使用
P/Invoke
调用必要的Win32 API函数的Hey, Scripting Guy! article,它可以告诉您哪个进程正在锁定文件。你可能会发现这本书读起来很有用。从本文中看,作用域中的关键Win32 API函数是:NtQuerySystemInformation
:除了其他功能外,还可以查询系统上打开的句柄。NtQueryObject
:查询有关句柄的附加信息。OpenProcess
:允许我们获得有关拥有句柄的进程的更多信息。DuplicateHandle
:在当前进程(例如ISE)中创建句柄的副本,以便我们可以对其执行其他操作。QueryDosDevice
:将逻辑驱动器(如驱动器C)转换为DOS设备标识符。