一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - PowerShell - Powershell ISE的抽象語法樹編程示例

Powershell ISE的抽象語法樹編程示例

2020-06-30 10:43腳本之家 PowerShell

這篇文章主要介紹了Powershell ISE的抽象語法樹編程示例,本文講解了抽象語法樹的一些概念,并給出了代碼實例,需要的朋友可以參考下

有一個讓我非常喜歡Windows PowerShell ISE的理由,就是它將它的基礎腳本對象模型暴露給用戶,這樣就允許用戶按照自己的方式和需要去自定義腳本體驗。
自定義ISE的核心是$psISE對象。$psISE對象允許用戶去控制ISE許多方面的功能。你可以從這里獲取關于$psISE的分層對象模型的介紹,和與這些對象相關聯的功能。

這篇文章會討論你怎樣利用PowerShell公開提供的解釋器接口,來結合ISE對象模型魅力,去創建腳本分析和快速定位的工具。

想象一下,你不得不分析一個相對龐大的PowerShell腳本。那這個腳本可能是別人寫的,也有可能是你自己幾個月前寫的,扔了好久了。PowerShell ISE已經做了件非常棒的工作了,它提供了腳本環境。你可以通過添加Add-On(附加工具)來擴充它的功能,讓你的腳本體驗更好,更高效。從PowerShell 3.0開始,腳本的抽象語法樹(AST)就可以使用語法解釋器接口非常方便的獲取了。下面的腳本行會獲取當前打開的ISE中的腳本的AST:

復制代碼 代碼如下:

$AbstractSyntaxTree = [System.Management.Automation.Language.Parser]::
ParseInput($psISE.CurrentFile.Editor.Text, [ref]$null, [ref]$null)

 

接下來讓我們查詢腳本中所有的函數:

 

復制代碼 代碼如下:

$functionsInFile = $AbstractSyntaxTree.FindAll({$args[0] -is
 [System.Management.Automation.Language.FunctionDefinitionAst]}, $true)

 

撇開函數定位的定義,如果我們能回到光標之前出現的位置,那將太漂亮了。實現這個也非常簡單。我們所要做的只是存儲這些行號,然后按照反轉順序反轉他們。(是否有人已經知道了,“堆棧”)

下面的腳本塊展示了展示了Go-To Definition的實現。

復制代碼 代碼如下:

#Define some useful global variables
 
$global:__ISEGoToAddOncurrLine=1
 
$global:__ISEGoToAddOncurrcol=1
 
$global:__ISEGoToAddOnlineToGoTo=1
 
$global:__ISEGoToAddOncolToGoTo=1
 
#We need two stacks - one each for line and column
 
$global:__ISEGoToAddOnstackOfLine = New-Object System.Collections.Stack
 
$global:__ISEGoToAddOnstackOfCol = New-Object System.Collections.Stack
 
#This script block has the logic for the implementation of the Go-To definition functionality
 
$global:__ISEGoToAddOnscriptBlockGoTo =
 
{
 
$AbstractSyntaxTree =[System.Management.Automation.Language.Parser]::ParseInput($psISE.CurrentFile.Editor.Text,[ref]$null, [ref]$null)
 
$functionsInFile = $AbstractSyntaxTree.FindAll(
 
{$args[0] -is[System.Management.Automation.Language.FunctionDefinitionAst]}, $true)
 
#Get the text of the line where we have the cursor
 
$str = $psISE.CurrentFile.Editor.CaretLineText
 
#Store them on the stack for later use
 
$global:__ISEGoToAddOnstackOfLine.Push($psISE.CurrentFile.Editor.CaretLine)
 
$global:__ISEGoToAddOnstackOfCol.Push($psISE.CurrentFile.Editor.CaretColumn)
 
$global:__ISEGoToAddOncurrLine = $global:__ISEGoToAddOnstackOfLine.Peek()
 
$global:__ISEGoToAddOncurrcol = $global:__ISEGoToAddOnstackOfCol.Peek()
 
#Get the selected text so that it can be used for searching existing functions
 
$selectedFunction = $psISE.CurrentFile.Editor.SelectedText
 
#Ensure that the cursor is somewhere between the word boundaries of the function
 
$functionsInFile | %{if(($str.Contains($_.name)) `
 
–and ($global:__ISEGoToAddOncurrcol -ge
 
$str.IndexOf($_.name)) `
 
-and ($global:__ISEGoToAddOncurrcol -le
 
($str.IndexOf($_.name)+$_.name.length))
 
)
 
{$selectedFunction = $_.name}
 
}
 
if($selectedFunction -ne "")
 
{
 
#See if the selected function exists in the current open file
 
$functionToGoTo = $functionsInFile | ?{$_.name -eq "$selectedFunction"}
 
$global:__ISEGoToAddOnlineToGoTo = $functionToGoTo.Extent.StartLineNumber
 
$global:__ISEGoToAddOncolToGoTo = $functionToGoTo.Extent.StartColumnNumber
 
}
 
if($functionToGoTo -eq $null)
 
{
 
try
 
{
 
$comm = Get-Command -Name "$selectedFunction" -ErrorAction SilentlyContinue
 
$comm.Definition | Out-GridView
 
}
 
catch [System.Exception]
 
{
 
}
 
}
 
else
 
{
 
#Select the function definition, assuming the function name immediately follows the keyword 'function'
 
try
 
{
 
$psise.CurrentFile.Editor.Select($global:__ISEGoToAddOnlineToGoTo,
 
($global:__ISEGoToAddOncolToGoTo+9),
 
$global:__ISEGoToAddOnlineToGoTo,
 
($global:__ISEGoToAddOncolToGoTo+8+$selectedFunction.length+1))
 
}
 
catch [System.Exception]
 
{
 
}
 
}
 
}

 

補充一下,Go-To Definition 功能,如果當前Powershell會話中存在的話,以上腳本會顯示選中文本的定義。(另外,上面的腳本只是一個簡單的例子,假如你的“function”關鍵字和函數名出現在腳本的同一行。這在PowerShell中并不是必須的,所以如果你的腳本風格不同,你可能需要微調一下邏輯。)

接下來應當是在Add-on(附加工具)菜單上添加這些腳本,并把它作為選中腳本的一個命令。下面兩行就可以做這件事。

復制代碼 代碼如下:

$global:__ISEGoToAddOnsb1 =
{& $global:__ISEGoToAddOnscriptBlockGoTo | Out-Null}
$null=$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add(
"Go do definition", $global:__ISEGoToAddOnsb1, "F12")

 

現在來看看我們怎樣實現Go-Back 功能,使用我們定義的全局堆棧,幾行代碼即可:

 

復制代碼 代碼如下:

$global:__ISEGoToAddOnscriptBlockGoBack =
 
{
 
try
 
{
 
#Pop the line and column numbers from the stack to do a reverse traversal
 
$global:__ISEGoToAddOncurrLine =
 
$global:__ISEGoToAddOnstackOfLine.Pop()
 
$global:__ISEGoToAddOncurrcol =
 
$global:__ISEGoToAddOnstackOfCol.Pop()
 
$psISE.CurrentFile.Editor.SetCaretPosition(
 
$global:__ISEGoToAddOncurrLine, $global:__ISEGoToAddOncurrcol)
 
$psISE.CurrentFile.Editor.SelectCaretLine();
 
}
 
catch [System.Exception]
 
{
 
}
 
}
 
$global:__ISEGoToAddOnsb2 = {& $global:__ISEGoToAddOnscriptBlockGoBack | Out-Null}
 
$null=$psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Go Back",$global:__ISEGoToAddOnsb2, "Shift+F12")

 

就到這里了,只用了一些PowerShell代碼就實現了Visual Studio中的Go-To Definition (轉向定義)和Go-Back(返回)功能。

你還可以繼續擴展這個腳本,讓它包含這些任務:諸如顯示腳本中所有函數,點擊函數轉到函數定義。作為大家進一步擴展功能的鼓勵,我給你看下我的 ISE附加工具現在的樣子。

Powershell ISE的抽象語法樹編程示例

擴展PowerShell ISE 中的 “附加工具”菜單

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色狠狠婷婷97 | 精品视频免费在线观看 | 久久这里都是精品 | 欧美一区二区三区精品影视 | 色综七七久久成人影 | 亚洲精品卡1卡二卡3卡四卡 | 亚洲男gay同性同志 亚洲免费在线看 | 欧美 国产 日韩 第一页 | 99热精品69堂国产 | 亚洲视频一 | 九九99亚洲精品久久久久 | 欧美骚熟| 手机在线免费观看日本推理片 | 97色| 1313午夜精品久久午夜片 | 日韩香蕉视频 | 亚洲高清色图 | 久久九九亚洲精品 | 欧美亚洲天堂 | 国产青草视频在线观看免费影院 | 陈峰姚瑶全集小说无删节 | 欧美午夜网站 | 欧美视频一区二区三区在线观看 | 99re热这里只有精品视频 | 日韩精品 欧美 | 手机在线免费观看高清 | 美女禁区视频无遮挡免费看 | mm131亚洲| 91看片淫黄大片在看 | 9966国产精品视频 | 国产综合网站 | 欧美在线成人免费国产 | 国产亚洲欧美在线中文bt天堂网 | 国产亚洲人成网站在线观看不卡 | 色欧美亚洲 | 亚洲欧美优优色在线影院 | 国内精品视频一区二区三区 | 免费看男人使劲躁女人小说 | 暖暖 免费 高清 日本 中文 | 调教扩张宫颈女人惨叫 | 魔法满屋免费观看完整版中文 |