PowerShell Studio 工作原理

PowerShell Studio 2012 浅析 2


背景

今天QQ群中CodeCook问了个问题,在PowerShell Studio 2012 工程中创建了一个project,包含了两个窗体,一个主窗体,一个子窗体。在主窗体的按钮单击事件中,启动子窗体。这用c#在vs环境下实现,估计一分钟就够了;在PowerShell ISE下,脚本写得再溜,也得十一二分钟吧。在PowerShell Studio 2012中用一分钟也就够了,这也算体现了PowerShell Studio 2012的价值了。

PowerShell Studio 是什么

PowerShell Studio是一套基于PowerShell的包含脚本编辑,脚本调试,Windows Form设计等功能的集成开发环境(IDE)。其最大的亮点是支持拖拽控件式的Windows Form设计

PowerShell Studio的调用原理

理解了这个问题,纠结CodeCook的问题自然迎刃而解。

fprojs工程文件

PowerShell Studio的工程文件后缀名为:fprojs 。文件内容自然包含了整个工程的文件清单:

<ProjectState>
  <Version>1.0</Version>
  <FileID>fc295821-bae7-4898-a6c5-bb545f8a1bf4</FileID>
  <OpenFiles>
    <File>Globals.ps1</File>
    <File>Startup.pfs</File>
    <File>MainForm.pff</File>
    <File>child.pff</File>
  </OpenFiles>
</ProjectState>

Globals.ps1文件

Globals.ps1文件为一个原汁原味的PowerShell脚本文件,内面定义一些全局变量或者函数

Startup.pfs文件

Startup.pfs为工程文件的入口,类似C#中的main函数。默认内容为:

function Main {
	Param ([String]$Commandline)
	if((Call-MainForm_pff) -eq "OK")
	{

	}
	$global:ExitCode = 0 #Set the exit code for the Packager
}

其中关键一行Call-MainForm_pff,用来调用启动主窗体,格式为Call-【窗体名】_pff,这也是本篇博文的灵魂。那也就是意味着在接下的按钮的click事件中我是不是可以这样 Call-ChildForm_pff 调用子窗体,是的,完全正确。

但是CodeCook犯了个小错误,直接F5运行,一直提示有错误。为什么,因为F5是运行当前脚本文件,而这种pff文件是一个伪脚本,不是原汁原味的PowerShell脚本文件,所以报错。应当使用Ctrl+F4运行整个工程。效果如下:

PowerShell Studio 工作原理

PowerShell Studio 工作原理

Form.pff文件

那我们再看看pff的文件结构,结构非常清晰,甚至比visual studio自动生成的文件design.cs还清晰(有过之,而无不及),前面使用xml定义控件。

  <Object type="System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="MainForm" children="Controls">
    <Property name="ClientSize">223, 122</Property>
    <Property name="Name">MainForm</Property>
    <Property name="StartPosition">CenterScreen</Property>
    <Property name="Text">Main Form</Property>
    <Event name="Load">OnLoadFormEvent</Event>
    <Object type="System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" name="btnClickMe" children="Controls">
      <Property name="Location">63, 41</Property>
      <Property name="Name">btnClickMe</Property>
      <Property name="Size">109, 44</Property>
      <Property name="TabIndex">1</Property>
      <Property name="Text">亲爱的,点我呀</Property>
      <Property name="UseVisualStyleBackColor">True</Property>
      <Event name="Click">btnClickMe_Click</Event>
    </Object>
  </Object>

紧接着,利用CDATA定义控件对应的事件

  <Code><![CDATA[
$OnLoadFormEvent={
#TODO: Initialize Form Controls here
}

$btnClickMe_Click={
	$this.Enabled = $False
	#TODO: Place custom script here
	Call-ChildForm_pff
	#Process the pending messages before enabling the button
	[System.Windows.Forms.Application]::DoEvents()
	$this.Enabled = $True
}
]]></Code>

最后定义引用版本信息等:

  <Assemblies>
    <Assembly>System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</Assembly>
    <Assembly>System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</Assembly>
  </Assemblies>

用小学老师作文评语来评价就是:”层次分明,脉络清晰”

导出为一个独立的PowerShell脚本

不管过程怎么花哨,最终得回归到一个Powershell脚本文件,这才是PowerShell Studio的真正归宿。导出后的ps1文件中包含了每个工程文件的名称和源文件的加密数据:

#region Source: Startup.pfs
#region File Recovery Data (DO NOT MODIFY)
<#RecoveryData:
CwcAAB+LCAAAAAAABAC9Vdtu2zAMfR+wf/AHZJY9x0kLqAYCBx2KYVtQF9teFYVOhcqSoUsD//2U
zNfY6YY+BH4xDy+HokQSPwKVr6CqNTEk+fjB8/APxfZMEH7POHwnBSSZIcrY0i9zjdFIe/I5Sj9B
aSZFEvqfMeoDJ4uV1lBsOQN9kjukSrJKGyj8b0SQPRQgjL+yRhbEOOeZV0e5i/zg+M281HJjFdwJ
sEYRPvM21sWlX6F6ki/gDMNtHt3EC7KLFnOIYoxapmnmjmP+vxzb5ZLENF6Et9Ecgpvbf3L4v5jY
yYP276Uq9FUY14ocmNi/hyuI8jhf5mG4iwMSkTe4Ck2l4mx7nRO5N3oVot8Fv86BmAJqpKoyUK+M
wrsextuX1YpN5+ENoS+u0VST1BcQ4ALXYmfQdvcJRJNoDT7Qus0HpkPUtTfLQZtUwamzkxCjEdZa
p1a7EdDoe7EvKTacmNz1VvLJxW2FVv1oRfa0SgKM6r/OUR5AZc/AeTOv3Pgag3Wx0LBaOANqFTOV
hxpk6HA2G7tzTKIbJXeWmrH1JUWNn1/VFLoGTRUrh2VGk2gqi5KIql/1cySVZeU2wfPgasbYgzCg
3LY4S3Aanlwtfx0uq1xmx5UxzLWHYDRYQ6j3+t1b6C+/P5RBcLgLBwAA#>
#endregion
#----------------------------------------------
#region Import Assemblies
#----------------------------------------------
[void][Reflection.Assembly]::Load("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
[void][Reflection.Assembly]::Load("System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
[void][Reflection.Assembly]::Load("System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
[void][Reflection.Assembly]::Load("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
[void][Reflection.Assembly]::Load("System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
[void][Reflection.Assembly]::Load("System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
[void][Reflection.Assembly]::Load("System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
#endregion Import Assemblies

我们看看之前提到的Call-ChildForm_pff变成什么样子了,贴出一段,这下很眼熟了吧。

#----------------------------------------------
#region Generated Form Objects
#----------------------------------------------
[System.Windows.Forms.Application]::EnableVisualStyles()
$formChildForm = New-Object 'System.Windows.Forms.Form'
$InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState'
#endregion Generated Form Objects
#……
#region Generated Form Code
#----------------------------------------------
#
# formChildForm
#
$formChildForm.ClientSize = '249, 109'
$formChildForm.Name = "formChildForm"
$formChildForm.Text = "Child Form"
$formChildForm.add_Load($formChildForm_Load)
#endregion Generated Form Code

#----------------------------------------------

#Save the initial state of the form
$InitialFormWindowState = $formChildForm.WindowState
#Init the OnLoad event to correct the initial state of the form
$formChildForm.add_Load($Form_StateCorrection_Load)
#Clean up the control events
$formChildForm.add_FormClosed($Form_Cleanup_FormClosed)
#Store the control values when form is closing
$formChildForm.add_Closing($Form_StoreValues_Closing)
#Show the Form
return $formChildForm.ShowDialog()

写作最后

PowerShell Studio像PowerShell一样,其方便成就了其强大,可以用来做一些的Windows窗体工具。但是考虑到PowerShell解释性语言的性能,你会用它做软件吗?反正我是不会。

本文链接: https://www.pstips.net/powershell-studio-2012-simple-analysis.html
请尊重原作者和编辑的辛勤劳动,欢迎转载,并注明出处!

关于 Mooser Lee

我是一个Powershell的爱好者,创建了PowerShell中文博客,热衷于Powershell技术的搜集和分享。本站部分内容来源于互联网,不足之处敬请谅解,并欢迎您批评指正。

回复 Mooser Lee 取消回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

2 条评论 “PowerShell Studio 2012 浅析