我编写了一个函数来检查 excel 文件是否被共享网络驱动器中的另一个进程/用户使用/锁定,如果使用,暂停脚本并继续检查直到它可用,因为下一个操作是将其移出其文件夹。但是,当我使用 System.IO 读取文件时,它不会打开文件。我已经在本地驱动器上进行了测试,这确实打开了文件,但这在网络驱动器中不起作用吗?
$IsLocked = $True
Function Test-IsFileLocked {
[cmdletbinding()]
Param (
[parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
[Alias('FullName','PSPath')]
[string[]]$Path
)
Process {
while($isLocked -eq $True){
If ([System.IO.File]::Exists($Path)) {
Try {
$FileStream = [System.IO.File]::Open($Path,'Open','Write')
$FileStream.Close()
$FileStream.Dispose()
$IsLocked = $False
} Catch {
$IsLocked = $True
echo "file in use, trying again in 10 secs.."
Start-Sleep -s 10
}
}
}
}
}
这是代码在我的函数中没有拾取/打开 excel 文件的地方
$FileStream = [System.IO.File]::Open($Path,'Open','Write')
这是程序调用函数的地方。循环访问网络驱动器中的项目文件夹,如果项目与模式匹配,则将调用该函数来检查文件是否正在使用中:
$DirectoryWithExcelFile = Get-ChildItem -Path "Z:NetworkDriveFolder"
$DestinationFolder = "Z:DestinationFolder"
$pattern = "abc"
foreach($file in $DirectoryWithExcelFile){
if($file.Name -match $pattern){
Test-IsFileLocked -Path $file
$destFolder = $DestinationFolder+$file.Name
Move-item $file.FullName -destination $destFolder
break
}
}
您必须将关闭并处置在尝试的最后部分,因此如果它引发异常,它会处理锁。也不能保证这是文件锁定异常,因此您最好throw
异常,捕获预期的异常或将其写出来
$IsLocked = $True
Function Test-IsFileLocked {
[cmdletbinding()]
Param (
[parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
[Alias('FullName','PSPath')]
[string]$Path
)
Process {
while($isLocked -eq $True){
If ([System.IO.File]::Exists($Path)) {
Try {
$FileStream = [System.IO.File]::Open($Path,'Open','Write')
$IsLocked = $False
} Catch [System.IO.IOException] {
$IsLocked = $True
echo "file in use, trying again in 10 secs.."
Start-Sleep -s 10
} Catch {
# source https://stackoverflow.com/questions/38419325/catching-full-exception-message
$formatstring = "{0} : {1}`n{2}`n" +
" + CategoryInfo : {3}`n" +
" + FullyQualifiedErrorId : {4}`n"
$fields = $_.InvocationInfo.MyCommand.Name,
$_.ErrorDetails.Message,
$_.InvocationInfo.PositionMessage,
$_.CategoryInfo.ToString(),
$_.FullyQualifiedErrorId
$formatstring -f $fields
write-output $formatstring
} finally {
if($FileStream) {
$FileStream.Close()
$FileStream.Dispose()
}
}
}
}
}
}
编辑:路径应该是字符串,而不是字符串数组,除非您有多个路径,在这种情况下重命名为 $Paths
并循环遍历它们$Paths| % { $Path = $_; #do stuff here }