4

I am trying to print parts of several docx files. The code below works in Windows PowerShell 5.1, but not in PowerShell 7.3. I would like to understand why and help updating the code so it works in PowerShell 7.3.

$path = 'D:\SchoolWeb\DOCXtoPDF\test.docx' #Path to docx

$Word = New-Object -ComObject Word.Application #open MS Word app
$Word.Visible = $false #hide the MS Word app
$docx = $Word.Documents.Open($path) #Open the docx from the path into the open MS Word app

$pagesNum = $Word.ActiveDocument.ComputeStatistics([Microsoft.Office.Interop.Word.WdStatistic]::wdStatisticPages) #Get the number of pages in the docx
$max=$pagesNum-2 #Get the maximum pages because the last two pages are not important

$Missing    = [System.Reflection.Missing]::Value  # Default values
$BackGround = 0
$Append     = 0
$Range      = 4 #https://learn.microsoft.com/en-us/office/vba/api/word.wdprintoutrange
$OutputFileName = $Missing
$From       = $Missing # values I've tried "1"
$To     = $Missing # values I've tried $max
$Item       = 0
$Copies     = 1
#$Pages = $max # values I've tried 
if ($max -gt 1) { $Pages = "1-$max" } else { $Pages = "1" }
    
$Word.PrintOut([ref]$BackGround, [ref]$Append, [ref]$Range, [ref]$OutputFileName, [ref]$From, [ref]$To, [ref]$Item, [ref]$Copies, [ref]$Pages)

$docx.Close($false)
$Word.Quit()

In Powershell 7.3, I get a MethodException "Exception setting "PrintOut": Cannot convert the "1" value of type "string" to type "Object"."

I know this relates to the $Pages variable.

Here are some places I already looked:

Thank you for explaining why the code works in one PowerShell and not the other and helping me to correct the code so it works in PowerShell 7.3.

phuclv
  • 37,963
  • 15
  • 156
  • 475
mwb9aa
  • 41
  • 2
  • You have $pages commented out so I’d expect a missing argument error on the method (incorrect number of arguments) have you tried casting pages to [object] explicitly like the error claims it is failing to do? – Doug Maurer Nov 23 '22 at 00:30
  • Try using `[System.Type]::Missing` instead of `[System.Reflection.Missing]::Value` and remove the `[ref]` flag from in front of those variables: outputfilename, to, and from (or just using `[System.Type]::Missing` in their place) – Daniel Nov 23 '22 at 01:37
  • Actually, looks like you can use `[System.Reflection.Missing]::Value`, you just need to remove `[ref]` from in front of them -- `$Word.PrintOut([ref]$BackGround, [ref]$Append, [ref]$Range, [System.Reflection.Missing]::Value,[System.Reflection.Missing]::Value,[System.Reflection.Missing]::Value, [ref]$Item, [ref]$Copies, [ref]$Pages)` – Daniel Nov 23 '22 at 01:41
  • Actually again, just remove `[ref]` from all arguments. It is unneeded here. – Daniel Nov 23 '22 at 22:06
  • @DougMaurer, Yes. I did try that. I forgot to put that in the original question. – mwb9aa Nov 25 '22 at 21:25
  • @Daniel, Your solution doesn't give an error, but the printer doesn't print the document. I just had to remove the [ref]. – mwb9aa Nov 25 '22 at 21:43
  • 1
    @Daniel, Your solution did work, when I selected a different printer. How do I mark it as the answer to my question? – mwb9aa Nov 25 '22 at 22:12

1 Answers1

0

Not sure where it goes sideways...
I suspect the parameter types (not just pages) are not correctly aligned their position).
Anyways, to resolve your issue, I recommend you to use named parameters. See this answer: How to call a complex COM method from PowerShell?

$Word.GetType().InvokeMember('PrintOut', [System.Reflection.BindingFlags]::InvokeMethod,
    $null,  ## Binder
    $Word,  ## Target
    ([Object[]]1),  ## Args
    $null,  ## Modifiers
    $null,  ## Culture
    ([String[]]'Pages')  ## NamedParameters
)

or using the function in the referenced answer:

Invoke-NamedParameter $Word Printout @{ Pages = 1 }
iRon
  • 20,463
  • 10
  • 53
  • 79
  • I wasn't able to get your method to work. I got errors of Invoke-NamedParameter is not recognized as a name of a cmdlet, function, script file, or exe on the 1-line piece of code, and Exception calling InvokeMember with 8 arguments type mismatch when I tired the $Word.GetType() sample. I suspect the error is on my lack of understanding. Thanks for your help. – mwb9aa Nov 25 '22 at 22:01