Powershell — Поиск строк (в списке) в документе word

#list #powershell #search #word

#Список #powershell #Поиск #слово

Вопрос:

Я нашел некоторый код для поиска строк в документе Word. Я изменил его в соответствии со своими потребностями (мне нужно выполнить поиск по очень длинному списку строк). К сожалению, я получаю странную ошибку.

Во время выполнения сценария он открывает документ word, выполняет поиск в документе word, и вот тут становится странно, вместо того, чтобы закрыть документ и открыть следующий, он представляет мне диалоговое окно «сохранить как», и сценарий зависает, пока я не отменю его. Когда я отменяю его, мой сценарий продолжается.

Вот сценарий, который я использую, кто-нибудь увидит, куда я направляюсь на юг?

 $results = @{}  Write-Host "Loading getStringMatch into memory" -ForegroundColor DarkMagenta  Function getStringMatch {  # Loop through all *.doc files in the $path directory  Foreach ($file In $files)  {  Write-Host "Searching In ... $($File.FullName) " -ForegroundColor DarkYellow  $document = $application.documents.open($file.FullName,$false,$true)   $range = $document.content   If($range.Text -match ".{$($charactersAround)}$($findtext).{$($charactersAround)}"){  $properties = @{  File = $file.FullName  Match = $findtext  TextAround = $Matches[0]   }  $results  = @(New-Object -TypeName PsCustomObject -Property $properties)  }   $document.close()  Write-Host "Closing Document ... $($File.FullName) " -ForegroundColor Red  }   #If($results){  # $results | Export-Csv $output -NoTypeInformation  #}  $application.quit() }   $searchWords=Get-Content "C:TempUSDA_Search_For.txt" Foreach ($sw in $searchWords) {  Write-Host "Setting Variables ..." -ForegroundColor DarkMagenta  Set-StrictMode -Version latest  $path = "C:Temp"  $files = Get-Childitem $path -Include *.docx,*.doc -Recurse | Where-Object { !($_.psiscontainer) }  $output = "C:TempFound.csv"  $application = New-Object -comobject word.application  $application.visible = $False  $findtext = "First"  $charactersAround = 30  #$results = @{}    $findtext = $sw  Write-Host "Searching For ... $findtext" -ForegroundColor Green  getStringMatch   #clean up stuff  [System.Runtime.InteropServices.Marshal]::ReleaseComObject($application) | Out-Null  Remove-Variable -Name application  [gc]::collect()  [gc]::WaitForPendingFinalizers()    }  If($results){  $results | Export-Csv $output -NoTypeInformation  } import-csv $output  

Комментарии:

1. Получаете ли вы запрос на подтверждение до или после вывода на экран «Закрытие документа … lt;путь к файлуgt;»? Если раньше, попробуйте перейти $document.close() на $document.Close($false)

2.Кроме того, определите приведенный $application = New-Object -comobject word.application выше цикл foreach (только один раз). Удалите $application.quit() из getStringMatch функции и переместите ее ниже цикла foreach. После этого выполните очистку, чтобы освободить COM-объекты из памяти

3. @MathiasR.Jessen и Тео, это сработало!! Спасибо вам обоим. У меня есть еще один вопрос, если можно. Я думаю, что, возможно, я неправильно закодировал это. Я открываю и закрываю более 100 документов Word для каждой строки, которую ищу. Есть ли способ изменить приведенный выше код, чтобы открыть каждый документ Word только один раз и выполнить поиск по каждой строке, а затем перейти к следующему документу Word? Причина, по которой я спрашиваю, заключается в том, что моя тестовая папка с 25 документами и более чем 150 строками для поиска занимает более 5 минут.

4. Вы могли бы объединить все $searchWords с регулярным выражением ИЛИ | так, чтобы вам вообще не нужно было их зацикливать.. $searchWords= '({0})' -f ((Get-Content "C:TempUSDA_Search_For.txt | ForEach-Object { [regex]::Escape($_) }) -join '|')

5. @Тео, Это сработало Очаровательно!!! Сейчас он быстро разгорается. Большое спасибо!!