Troubles using Powershell and Word SaveAs()

1

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()
.net
powershell
ms-word
office-interop
asked on Stack Overflow Apr 7, 2016 by lit • edited Apr 7, 2016 by Deduplicator

2 Answers

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

answered on Stack Overflow Apr 8, 2016 by Nick • edited Apr 10, 2016 by Nick
0

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
answered on Stack Overflow Apr 12, 2016 by lit

User contributions licensed under CC BY-SA 3.0