【问题标题】:Powershell File Lock function is not opening excel FilePowershell文件锁定功能未打开excel文件
【发布时间】:2019-10-14 14:30:48
【问题描述】:

我编写了一个函数来检查共享网络驱动器中的另一个进程/用户是否正在使用/锁定 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
  }
}

【问题讨论】:

  • 你没有正确处理锁

标签: powershell network-drive filelock


【解决方案1】:

您必须在 try 的最后部分放置关闭和处置,因此如果它抛出异常,它会处置锁。也不能保证它是文件锁定异常,所以你最好throw 异常,捕获你期望的异常或write it out

$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 }

【讨论】:

  • 嗨 Lloyd 感谢您提供正确的 try/catch 结构,但问题是文件 $Path 甚至没有在这一行中打开“ $FileStream = [System.IO.File]::Open($路径,'打开','写入')”。它直接跳转到 Catch[System.IO.IOException]
  • 为什么路径是字符串数组?它不应该通过 $Path 找出每个单独的路径吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多