理解Powershell全局变量的用例

时间:2022-07-06 00:42:15

Recently, I've been working on a project where I try to create GUIs for my Powershell scripts. Even though, there seems to exists a lot of possibilities, I found one way to do it designed by a Microsoft PFE: Chris Conte.

最近,我在一个项目中尝试为Powershell脚本创建gui。尽管看起来有很多可能性,我还是找到了一种由微软PFE设计的方法:Chris Conte。

If you guys are interested you can find the article here.

如果你们感兴趣的话,可以在这里找到这篇文章。

Now, my question is related particularly to the loadDialog.ps1 script, which is basically the link between a XAML form and your original Powershell script. Here is the code:

现在,我的问题与loadDialog有关。ps1脚本,它基本上是XAML表单和原始Powershell脚本之间的链接。这是代码:

[CmdletBinding()]
Param(
  [Parameter(Mandatory=$True,Position=1)]
  [string]$XamlPath
)

[xml]$Global:xmlWPF = Get-Content -Path $XamlPath

#Add WPF and Windows Forms assemblies
try{
    Add-Type -AssemblyName PresentationCore,PresentationFramework,WindowsBase,system.windows.forms
} catch {
    Throw "Failed to load Windows Presentation Framework assemblies."
}

#Create the XAML reader using a new XML node reader
$Global:xamGUI = [Windows.Markup.XamlReader]::Load((new-object System.Xml.XmlNodeReader $xmlWPF))

#Create hooks to each named object in the XAML
$xmlWPF.SelectNodes("//*[@Name]") | %{
    Set-Variable -Name ($_.Name) -Value $xamGUI.FindName($_.Name) -Scope Global
    }

Since $xamGUI and newly created variables captured by the XAML reader are shared between scripts I can understand their global scope. My question is specific to this line:

XAML阅读器捕获的$xamGUI和新创建的变量在脚本之间共享,我可以理解它们的全局作用域。我的问题针对这一点:

[xml]$Global:xmlWPF = Get-Content -Path $XamlPath

$Global:xmlWPF = Get-Content -Path $XamlPath

Why is he using a global scope ? Is this in case we would want to use it somewhere else or there is something I'm missing? I'm still new to Powershell environnement and the snippet's author clearly has notoriety in the Powershell world, so I'm guessing there is a reason for this declaration but I can't get what this is.

他为什么要使用全球范围?如果我们想在别的地方使用它,或者我漏掉了什么?我对Powershell环境还不熟悉,而且这个代码片段的作者显然在Powershell世界中声名狼藉,所以我猜这个声明是有原因的,但我不知道这是什么。

1 个解决方案

#1


0  

The helper script is essentially "returning" things - the XML, form and all the controls - to the user as variables. For example, if there was a button labelled button1 in the XAML, the script would create a global variable $global:button1. You can then use this variable to attach an event handler: $button1.add_Click{ $Label1.Content = "Hello World" } It's in the event handler where the need for these global variables becomes obvious. You somehow have to pass the form controls to the event handler scriptblock - in this case, Label1. The simplest way to do this is to create the variables in a parent (e.g. global) scope and allow dynamic scoping to do the work for you. C# uses a similar (but lexically scoped) approach by making all of the controls members of the enclosing class.

助手脚本本质上是将XML、表单和所有控件作为变量“返回”给用户。例如,如果XAML中有一个名为button1的按钮,脚本将创建一个全局变量$global:button1。然后可以使用该变量附加一个事件处理程序:$button1。add_Click { Label1美元。Content = "Hello World"}事件处理程序中显然需要这些全局变量。您必须以某种方式将表单控件传递给事件处理程序scriptblock——在本例中是Label1。最简单的方法是在父作用域(例如全局作用域)中创建变量,并允许动态作用域为您完成工作。c#使用一种类似的(但在词法范围内)方法,使所有控件都属于封闭类。

#1


0  

The helper script is essentially "returning" things - the XML, form and all the controls - to the user as variables. For example, if there was a button labelled button1 in the XAML, the script would create a global variable $global:button1. You can then use this variable to attach an event handler: $button1.add_Click{ $Label1.Content = "Hello World" } It's in the event handler where the need for these global variables becomes obvious. You somehow have to pass the form controls to the event handler scriptblock - in this case, Label1. The simplest way to do this is to create the variables in a parent (e.g. global) scope and allow dynamic scoping to do the work for you. C# uses a similar (but lexically scoped) approach by making all of the controls members of the enclosing class.

助手脚本本质上是将XML、表单和所有控件作为变量“返回”给用户。例如,如果XAML中有一个名为button1的按钮,脚本将创建一个全局变量$global:button1。然后可以使用该变量附加一个事件处理程序:$button1。add_Click { Label1美元。Content = "Hello World"}事件处理程序中显然需要这些全局变量。您必须以某种方式将表单控件传递给事件处理程序scriptblock——在本例中是Label1。最简单的方法是在父作用域(例如全局作用域)中创建变量,并允许动态作用域为您完成工作。c#使用一种类似的(但在词法范围内)方法,使所有控件都属于封闭类。