Troubles using Powershell and Word SaveAs()

落花浮王杯 提交于 2019-12-11 13:23:35

问题


From examples on the net, I have cobbled together this script which I hope will save Word .doc files as plainText. It does not.

First, the Word window appears when I have given $word.Visible = $False.

Then, a dialog appears asking if I want to open a read-only copy. No one else has the document open. Why is it asking.

Finally, the error message says I have a type mismatch. Why is that?

PS H:\d2> .\wl.ps1
Processing : H:\d2\checklists\Extract checklist_20120306.doc
Name is now: H:\d2\checklists\Extract checklist_20120306.txt
Exception calling "SaveAs" with "2" argument(s): "Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))"
At H:\d2\wl.ps1:19 char:5
+     $opendoc.SaveAs([ref]$name.Value,[ref]$saveFormat)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : COMException

Here is the source code for the script.

$srcfiles = Get-ChildItem -Path . -Recurse -Filter "*.doc*"
$saveFormat = [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatText
$word = new-object -comobject word.application
$word.Visible = $False

ForEach ($doc in $srcfiles) {
    Write-Host "Processing :" $doc.fullname
    $name = Join-Path -Path $doc.DirectoryName -ChildPath $($doc.BaseName + ".txt")
    Write-Host "Name is now:" $name

    $opendoc = $word.documents.open($doc.FullName)
    $opendoc.SaveAs([ref]$name.Value,[ref]$saveFormat)
    $opendoc.Close()

    $doc = $null
}

$word.quit()

回答1:


Why is it asking to open read-only

You are using the Microsoft Word COM object,

COM objects are notorious for causing issues if you do not close them properly. In you script calling $word.quit wont close the word.exe process in most cases.

You are getting the error that the document is open because a process from a previous script run has not been closed. You might have clicked stop before the script got to $word.quit() of might have just not quit.

Save all your work and try Get-Process WINWORD | stop-Process -force This will kill all open word processes on your machine. I bet you it will work after that. But you haven't solved the problem of the script leaving the word doc open. Try adding adding this to the end of your script:

$word.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($word)
Remove-Variable word

Its how I kill COM object processes and it has never failed to stop a IE com object process, Should work the same for Word.

Why is there a type mismatch

You need to have the library loaded in powershell:

[Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Interop.Word") | Out-Null

You need to change your .SaveAs to change the filepath to system.object rather than system.string It was a change made in .net 4.0 apparently

$opendoc.SaveAs([ref][system.object]$name,[ref]$saveFormat)

Found the answer to the type mismatch error HERE




回答2:


Nick's answer is marked as the answer. This is the resulting script that worked in this situation. The cwd must be the parent directory of all .doc files to convert.

[Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Interop.Word") | Out-Null
$srcfiles = Get-ChildItem -Path . -Recurse -Filter "*.doc*"
$saveFormat = [Microsoft.Office.Interop.Word.WdSaveFormat]::wdFormatText
$word = new-object -comobject word.application
$word.Visible = $False

ForEach ($doc in $srcfiles) {
    Write-Host "Processing :" $doc.fullname
    $name = Join-Path -Path $doc.DirectoryName -ChildPath $($doc.BaseName + ".txt")

    Write-Host "Name is now:" $name

    $word.Visible = $False

    $opendoc = $word.documents.open($doc.FullName)
    $opendoc.SaveAs([ref][system.object]$name, [ref]$saveFormat)
    $opendoc.Close()

    $doc = $null
}

$word.quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($word) | Out-Null
Remove-Variable word


来源:https://stackoverflow.com/questions/36487507/troubles-using-powershell-and-word-saveas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!