Convert Word documents to PDF

by cookie.monster at 2013-01-29 13:15:20

Hi all,

A co-worker asked how simple it would be to convert Word documents to PDF. Very, I assume; we can use COM objects and automate everything. Whipped up a quick proof of concept from Hey, Scripting Guy! example. Then I started to get quite frustrated.

Exception calling "SaveAs" with "2" argument(s): "Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))"
At line:27 char:5
+ $doc.saveas([ref] $fullDestinationPath, [ref]$wdFormatPDF)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:slight_smile: , MethodInvocationException
+ FullyQualifiedErrorId : COMException


It didn’t work on my Windows 8 + Office 2013 machine. Okay, perhaps Microsoft changed something in Office 2013! Same error came up on Windows 7 + Office 2010.

Didn’t spend too much time troubleshooting, but didn’t find the answers I was looking for. Eventually stumbled on this. Figured it might be something to do with .NET 4.0; tested the script on Server 2008 R2 with Office 2010 and .NET 3.5 and it worked without issue!

Eventually found the author of the article above mentioning that the filename parameter takes in an object rather than a string. Changed the saveas filename parameter type from [ref] to [ref][system.object] and voila, it finally worked on my other systems!

#init
$inputFolder = "C:\temp"
$destinationFolder = "C:\temp"
$wdFormatPDF = 17

write-verbose "creating word com object"
$word = New-Object -ComObject word.application
$word.visible = $false

#set source files
$sourceFiles = Get-ChildItem -path $inputFolder -filter *.doc

foreach($sourceFile in $sourceFiles) {
#Full path for opening file
$fullPath = $sourceFile.fullname

#Get source file name and extension
$sourceFileName = $sourceFile.name
$sourceFileExtension = $sourceFile.Extension

#replace the extension with pdf, set the full destination path
$destinationFileName = $sourceFileName.replace("$sourceFileExtension", ".pdf")
$fullDestinationPath = Join-Path $destinationFolder $destinationFileName

write-verbose "opening $fullpath and saving as $fullDestinationPath"
$doc = $word.documents.open($fullPath)
$doc.saveas( [ref][system.object]$fullDestinationPath, [ref]$wdFormatPDF )
$doc.close()

}

$word.Quit()


Just a warning to those of you who run into this same issue. I was a bit surprised to see that there aren’t many google results that point to this. Am I doing something incorrectly? Or are people not using this functionality / running older versions of .NET? My apologies for the sloppy code : )
by DonJ at 2013-01-29 13:33:16
I think most sane people try not to use the Office COM interface if there’s any way to avoid it.