Do not use
shell=True
.
Try this example:
import os
import subprocess
from pathlib import Path
# My Windows 11 installation is broken
# The Path is missing in my environment variables
# I guess you could run powershell.exe directly without entering the whole Path
system_root = os.environ["SystemRoot"]
powershell_exe = Path(
r"%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe".replace("%SystemRoot%", system_root)
)
# A random script copied from internet
# source: https://www.mariotti.de/powershell-dialog/
ps_script = """
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$form = New-Object System.Windows.Forms.Form
$form.Text = 'My Title'
$form.Size = New-Object System.Drawing.Size(300,200)
$form.StartPosition = 'CenterScreen'
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = 'OK'
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = 'Cancel'
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = 'Please select a value:'
$form.Controls.Add($label)
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,40)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 80
[void] $listBox.Items.Add('Value1')
[void] $listBox.Items.Add('Value2')
[void] $listBox.Items.Add('Value3')
[void] $listBox.Items.Add('Value4')
[void] $listBox.Items.Add('Value5')
[void] $listBox.Items.Add('Value6')
[void] $listBox.Items.Add('Value7')
$form.Controls.Add($listBox)
$form.Topmost = $true
$result = $form.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$x = $listBox.SelectedItem
$x
)
"""
# here the process is called.
# it blocks the code until the process is done
# not using shell=True, which is unsafe
# input is stdin of the provess. If you choose utf8 as encoding, then you can use strings
# if encoding is not given, input expects bytes
print("Running process with Window")
proc = subprocess.run([powershell_exe], input=ps_script, encoding="utf8")
# if you want to hide the powershell window:
print("Running process without Window")
creationflags = subprocess.CREATE_NO_WINDOW
proc = subprocess.run([powershell_exe], input=ps_script, encoding="utf8", creationflags=creationflags)
I have no clue how you get Information from the powershell script, that you can use it in python after the process finished.
But the menu seems to work.