I am trying to slowly move towards more type-safe powershell scripts and therefore experimenting with explicitly setting types for all my variables. In the following, I attempt to instantiate a Word.Application
object and then quit out of it:
using namespace Microsoft.Office.Interop.Word
using namespace System.Management.Automation
$ErrorActionPreference = [ActionPreference]::"Stop"
[Application]$wordApp = new-object -comobject Word.Application
$wordApp.Quit()
Could anyone explain to me why, upon running this script I get the following error:
InvalidOperation: test.ps1:5 Line | 5 | [Application]$wordApp = new-object -comobject Word.Application | ~~~~~~~~~~~~~ | Unable to find type [Application].
What is the correct way to remediate this?
Could anyone explain to me why, upon running this script I get the following error: [
Unable to find type
]?
A using namespace
statement merely provides syntactic convenience: it allows you to reference already loaded types by their simple name, without having to use the namespace part (in the case at hand, [Application]
instead of [Microsoft.Office.Interop.Word.Application]
)
Thus, you must ensure separately that the assemblies containing the types of interest are loaded, either via using assembly
statements or Add-Type
calls.
Therefore:
# NOTE:
# Windows PowerShell only - doesn't work in PowerShell (Core) 7, as of v7.4.x
using assembly Microsoft.Office.Interop.Word
using namespace Microsoft.Office.Interop.Word
using namespace System.Management.Automation
$ErrorActionPreference = [ActionPreference]::Stop
[Application]$wordApp = New-Object -ComObject Word.Application
$wordApp.Name # Get and output the .Name property value, for demonstration purposes.
$wordApp.Quit()
Note:
This does not work in PowerShell (Core) 7, as of v7.4.x:
Generally, there seems to be a problem with loading well-known assemblies with using assembly
- see GitHub issue #11856.
However, even using Add-Type -AssemblyName
doesn't help in this case, because the PIAs (Primary Interop Assemblies) (such as Microsoft.Office.Interop.Word.dll
) are in an older part of the GAC (Global Assembly Cache) that PowerShell 7 does not consult by default. Trying to load such an assembly with an explicit path, i.e. via Add-Type -LiteralPath
, fails quietly; e.g.:
# !! Fails quietly in PowerShell (Core) 7
Add-Type -LiteralPath C:\WINDOWS\assembly\GAC_MSIL\Microsoft.Office.Interop.Word\15.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Word.dll`
office.dll
assembly by full path too, as detailed in GitHub issue #24627 (the latter's primary purpose is to report the unexpected quiet failure).