首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何与System.Manangement.Automation.Language合作..。天梯

如何与System.Manangement.Automation.Language合作..。天梯
EN

Stack Overflow用户
提问于 2020-04-14 17:22:03
回答 1查看 224关注 0票数 0

因此,我试图为office创建一个自定义的PsAnalyzer规则,这是我第一次使用基于$ast的命令/变量。结果我有点不知所措。

我一直在使用几个站点来了解[System.Management.Automation.Language]对象类,即

为了测试目的,我正在使用下面这个函数--看起来很诡异。

代码语言:javascript
复制
Function IE { 

[cmdletbinding()]

Param( 
    $Url,
    $IEWIDTH  = 550,
    $IeHeight = 450 
)


$IE = new-object -comobject InternetExplorer.Application

$IE.top  = 200 ; $IE.width      = $IEWIDTH ; $IE.height  = $IEHEIGHT
$IE.Left = 100 ; $IE.AddressBar = $FALSE   ; $IE.visible = $TRUE
$IE.navigate( "file:///$Url" )

}

然后,使用下面的代码,我希望$IEWIDTH是唯一失败的param。

代码语言:javascript
复制
Function Measure-PascalCase {
<#
.SYNOPSIS
The variables names should be in PascalCase.
.DESCRIPTION
Variable names should use a consistent capitalization style, i.e. : PascalCase.
.EXAMPLE
Measure-PascalCase -ScriptBlockAst $ScriptBlockAst
.INPUTS
[System.Management.Automation.Language.ScriptBlockAst]
.OUTPUTS
[Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]]
.NOTES
https://msdn.microsoft.com/en-us/library/dd878270(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/ms229043(v=vs.110).aspx
https://mathieubuisson.github.io/create-custom-rule-psscriptanalyzer/
#>

[CmdletBinding()]
[OutputType([Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord[]])]
Param
(
    [Parameter(Mandatory = $True)]
    [ValidateNotNullOrEmpty()]
    [System.Management.Automation.Language.ScriptBlockAst]
    $ScriptBlockAst
)

Process {

    $Results = @()

    try {
        #region Define predicates to find ASTs.

        [ScriptBlock]$Predicate = {
            Param ([System.Management.Automation.Language.Ast]$Ast)

            [bool]$ReturnValue = $false

            if ( $Ast -is [System.Management.Automation.Language.ParameterAst] ){

                [System.Management.Automation.Language.ParameterAst]$VariableAst = $Ast

                if ( $VariableAst.Left.VariablePath.UserPath -eq 'i' ){
                    $ReturnValue = $false
                } elseif ( $VariableAst.Left.VariablePath.UserPath.Length -eq 3 ){
                    $ReturnValue = $false
                } elseif ($VariableAst.Left.VariablePath.UserPath -cnotmatch '^([A-Z][a-z]+)+$') {
                    $ReturnValue = $True
                }

            }

            return $ReturnValue
        }
        #endregion

        #region Finds ASTs that match the predicates.
        [System.Management.Automation.Language.Ast[]]$Violations = $ScriptBlockAst.FindAll($Predicate, $True)

        If ($Violations.Count -ne 0) {

            Foreach ($Violation in $Violations) {

                $Result = New-Object `
                        -Typename "Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.DiagnosticRecord" `
                        -ArgumentList "$((Get-Help $MyInvocation.MyCommand.Name).Description.Text)",$Violation.Extent,$PSCmdlet.MyInvocation.InvocationName,Information,$Null

                $Results += $Result
            }
        }
        return $Results
        #endregion
    }
    catch {
        $PSCmdlet.ThrowTerminatingError($_)
    }
}
}
Export-ModuleMember -Function Measure-*

相反,我得到了:

代码语言:javascript
复制
Line Extent          Message                                                                        
---- ------          -------                                                                        
6 $Url            Variable names should use a consistent capitalization style, i.e. : PascalCase.
7 $IEWIDTH  = 550 Variable names should use a consistent capitalization style, i.e. : PascalCase.
8 $IeHeight = 450 Variable names should use a consistent capitalization style, i.e. : PascalCase.
6 $Url            Variable names should use a consistent capitalization style, i.e. : PascalCase.
7 $IEWIDTH  = 550 Variable names should use a consistent capitalization style, i.e. : PascalCase.
8 $IeHeight = 450 Variable names should use a consistent capitalization style, i.e. : PascalCase.

对我做错了什么有什么想法吗?我找到了另一个站点这里,如果我使用该方法一次测试单个变量,我就会得到我希望看到的结果。

要做到这一点,在函数IE的末尾添加以下一行,

代码语言:javascript
复制
[System.Management.Automation.Language.Parser]::ParseInput($MyInvocation.MyCommand.ScriptContents, [ref]$null, [ref]$null)

下面的代码将给出长度数字。

代码语言:javascript
复制
$stuffast = .\FunctionIe.ps1

$left = $Stuffast.FindAll({$args[0] -is [System.Management.Automation.Language.AssignmentStatementAst]},$true) 

$left[0].Left.Extent.Text.Length

$left[0].Left.VariablePath.UserPath.Length
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-14 17:57:20

AssignmentStatementAst具有LeftRight(-hand)值属性不同,ParameterAst具有NameDefaultValue属性,因此您需要在谓词块中使用Name

代码语言:javascript
复制
$predicate = {
    # ...
    if ( $Ast -is [System.Management.Automation.Language.ParameterAst] ) {

        [System.Management.Automation.Language.ParameterAst]$VariableAst = $Ast

        if ( $VariableAst.Name.VariablePath.UserPath -eq 'i' ) {
            $ReturnValue = $false
        }
        elseif ( $VariableAst.Name.VariablePath.UserPath.Length -eq 3 ) {
            $ReturnValue = $false
        }
        elseif ($VariableAst.Name.VariablePath.UserPath -cnotmatch '^([A-Z][a-z]+)+$') {
            $ReturnValue = $True
        }
    }
    # ...
}

或者,翻转谓词逻辑,搜索父节点为VariableExpressionAstAssignmentStatementAstParameterAst节点之一。

代码语言:javascript
复制
$predicate = {
  param($ast)

  $ValidParents = @(
    [System.Management.Automation.Language.ParameterAst]
    [System.Management.Automation.Language.AssignmentStatementAst]
  )

  if($ast -is [VariableExpressionAst] -and $ValidParents.Where({$ast -is $_}, 'First')){
    [System.Management.Automation.Language.VariableExpressionAst]$variableAst = $ast

    # inspect $variableAst.VariablePath here
  }

  return $false
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61213574

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档