Функция блокировки файлов Powershell не открывает файл Excel - PullRequest
0 голосов
/ 29 мая 2019

Я написал функцию, чтобы проверить, используется ли файл 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
  }
}

1 Ответ

0 голосов
/ 29 мая 2019

Вы должны поместить закрытие и избавиться в заключительную часть попытки, поэтому, если он выдает исключение, он удаляет блокировку. Нет гарантии, что это исключение блокировки файла, поэтому вам лучше 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()
                    }
                }           
            }
          }     
     }
} 

Edit: Путь должен быть строкой, а не строковым массивом, если только у вас нет нескольких путей, в этом случае переименуйте их в $Paths и переберите их $Paths| % { $Path = $_; #do stuff here }

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...