在powershell中执行wpf脚本的方法
WPF & PowerShell – Part 1 ( Hello World & Welcome to the Week of WPF )
Welcome to the Week of WPF. During the next 7 days, I’ll help show you how you can use WPF and PowerShell together.
PowerShell could always script almost everything in .NET, but, prior to the recent CTP2 you could not script Windows Presentation Foundation (WPF) in PowerShell.
Now you can script everything that WPF can do within PowerShell.
This means you can write pretty sleek looking UIs in nice little PowerShell scripts.
There are a lot of things you can do with this capability, but let’s start things off simple.
Windows Presentation Foundation (WPF) is a set of .NET libraries for making next-generation user interfaces. In order to script WPF classes, you have to start them in a Single Threaded Apartment (STA). Luckily, starting in CTP2, you can run code in an STA a few ways in PowerShell.
In order to script WPF, you have to do one of three things:
· Run the Script in Graphical PowerShell, where WPF scripts will run without any changes because Graphical PowerShell runspaces are STA.
· Run the script in PowerShell.exe and add the –STA script
· Create a background runspace that is STA, and run the script in the background runspace
In this post, I’ll show you a “Hello World” script, and how to run it in each of the three modes.
First, let’s write our “Hello World” script. Open up Graphical PowerShell (gPowerShell.exe) and create a new script file (CTRL + N).
Here’s the Hello World file:
$window = New-Object Windows.Window
$window.Title = $window.Content = “Hello World. Check out PowerShell and WPF Together.”
$window.SizeToContent = “WidthAndHeight”
$null = $window.ShowDialog()
Now in Graphical PowerShell, you should be able to just run it and be done.
You can run the current script in Graphical PowerShell with F5 or the Green Run button in the upper left of the editor.
Now let’s run the script in STA Mode PowerShell (Run PowerShell –sta). Save it as “HelloWorld.ps1”
Since PowerShell.exe –sta doesn’t load up WPF’s assemblies, lets run these three lines to add the references:
Add-Type –assemblyName PresentationFramework
Add-Type –assemblyName PresentationCore
Add-Type –assemblyName WindowsBase
.\HelloWorld.ps1
Now you have a Hello World in WPF from the console version of PowerShell.
Finally, you can embed scripts to generate WPF inside of an application or a background runspace. This has some advantages over the first two approaches… namely, without a background
The code below will create a background runspace and set the two properties required to make WPF work in a PowerShell runspace, ApartmentState and ThreadOptions. ApartmentState determines if the runspace PowerShell is single or multithreaded (WPF requires single threaded), and if the same thread is used every time a command is run, or if a new thread is created each time. For WPF scripting to work in a runspace, you have to set ApartmentState to “STA” and ThreadOptions to “ReuseThread”. In the code below, the first 3 lines set up the runspace, the next 10 lines ensure that runspace is able to load WPF classes, and the final 4 lines run our original HelloWorld.ps1
# Create a runspace to run Hello World
$rs = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
$rs.ApartmentState, $rs.ThreadOptions = “STA”, “ReuseThread”
$rs.Open()
# Reference the WPF assemblies
$psCmd = {Add-Type}.GetPowerShell()
$psCmd.SetRunspace($rs)#这里需要更改为$psCmd.Runspace = $rs
$psCmd.AddParameter("AssemblyName", "PresentationCore").Invoke()
$psCmd.Command.Clear()#这个不需要
$psCmd = $psCmd.AddCommand("Add-Type")
$psCmd.AddParameter("AssemblyName", "PresentationFramework").Invoke()
$psCmd.Command.Clear()
$psCmd = $psCmd.AddCommand("Add-Type")
$psCmd.AddParameter("AssemblyName", "WindowsBase").Invoke()
$sb = $executionContext.InvokeCommand.NewScriptBlock(
(Join-Path $pwd "HelloWorld.ps1")
)
$psCmd = $sb.GetPowerShell()
$psCmd.SetRunspace($rs)
$null = $psCmd.BeginInvoke()
This is just a taste of some of the fun that PowerShell and WPF can have together, and how to get it working. You can now use everything in WPF in a PowerShell script.
During the Week of WPF, I will post one script each day that will take us a little further down the rabbit hole of what PowerShell and WPF can do together. After the week of WPF is done, keep your eyes on this space, because every Wednesday, I’ll try to post a “WPF Wednesday Widget” that uses showcase using PowerShell and WPF together.
Hope this Helps,
James Brundage [MSFT]