PowerShell 7.0 doesn't exit script

Created on 20 Mar 2020  路  5Comments  路  Source: PowerShell/PowerShell

I've written a small program with PowerShell 5 which works. With PowerShell 7, the script stops executing.
This is a minimal sample I could build to reproduce the issue.
Without the dialog or the Out-Speech function, it's working.
I don't know why this combination isn't working.

I start my script with a small batch

pwsh.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0test.ps1"
pause

and

powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%~dp0test.ps1"
pause

Steps to reproduce

Start the script and close the window.

function Ask4Password()
{
    $pwdForm = New-Object System.Windows.Forms.Form
    $pwdForm.Text = 'Please enter password'
    $pwdForm.Size = New-Object System.Drawing.Size(300,140)
    $pwdForm.StartPosition = 'CenterScreen'
    $pwdForm.KeyPreview = $true
    $pwdForm.Topmost = $true

    [void] $pwdForm.ShowDialog()

    return 'abc'
}

function Out-Speech( $text )
{
    $speechy = New-Object 鈥揅omObject SAPI.SPVoice
    [void]$speechy.Speak( $text, 1 ) # 1 = async
}

# only needed for PowerShell 5
[void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')

Ask4Password

Write-Host 'Wrong Password'
Out-Speech 'Wrong Password'

Expected behavior

Script should exit like with PowerShell 5

Actual behavior

Execution stops

Environment data

Name                           Value
----                           -----
PSVersion                      7.0.0
PSEdition                      Core
GitCommitId                    7.0.0
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Issue-Question WG-Engine

Most helpful comment

Follow works in PowerShell Core:

[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
$pwdForm = New-Object System.Windows.Forms.Form

All 5 comments

Follow works in PowerShell Core:

[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
$pwdForm = New-Object System.Windows.Forms.Form

I wouldn't be at all surprised if the COM object either works differently with .NET Core or simply doesn't work. I've not had a great many COM objects work well in .NET Core.

The hang is definitely worth investigating.

Pragmatically speaking, the problem only arises due to the _asynchronous_ call to .Speak(), and even though Windows PowerShell doesn't _hang_, the speech output _doesn't actually work_ - unless you make the call _synchronous_, simply by omitting the 1 argument: $speechy.Speak($text)

You can also avoid the hang if you explicitly release the COM component before exiting your script (though speech output still won't work): [System.Runtime.InteropServices.Marshal]::ReleaseComObject($speechy)


@Jawz84, .NET Core 3 added WinForms and WPF support (on Windows), so PowerShell 7 automatically supports it too.

@Tragen, as an aside, I suggest using the PowerShell-idiomatic way of loading a well-known assembly (by simple name):
Add-Type -AssemblyName System.Windows.Forms, rather than the declared-obsolete [System.Reflection.Assembly]::LoadWithPartialName method.

Thanks for the hint about loading the the assembly. It's an old script.

I also think you should investigate it.
It's not a problem about COM not working, But the async speed ouput or something else seems to block the exit.

Was this page helpful?
0 / 5 - 0 ratings