通过包含函数名称的变量间接调用函数
Invoking a function indirectly, via a variable containing the function name
我正在将一个 XML 节点导入变量 XmlInstallNode,然后动态构建我要调用的函数。
如果我直接通过函数名称调用函数,一切都很好,但是如果在调用命令中使用 $functionName 调用它,那么参数 -App - 被转换为字符串,而它应该是 System.Xml.XmlLinkedNode。我已经尝试转换它并使用 Invoke-Expressions 和 Invoke-Command 的不同方法但没有成功...
我收到这个错误,这有点道理:
无法处理参数 'App' 的参数转换。无法将类型 "System.String" 的“$app”值转换为类型 "System.Xml.XmlElement"
function global:XtrInstall{
try
{
$error=$false
XtrLog -Level INFO -FunctionName $MyInvocation.MyCommand -Msg "Installing Apps..."
XtrLog -Level DEBUG -FunctionName $MyInvocation.MyCommand -Msg "Getting available Apps from config file."
$XmlInstallNode=XtrGet-XmlInstall
if($XmlInstallNode.Apps)
{
foreach($app in $XmlInstallNode.apps.app)
{
$functionName = "$("XtrInstall-")$($app.Name)"
XtrLog -Level DEBUG -FunctionName $MyInvocation.MyCommand -Msg "$("Building function name: ")$($functionName)"
if (Get-Command $functionName -errorAction SilentlyContinue)
{
XtrLog -Level DEBUG -FunctionName $MyInvocation.MyCommand -Msg "$("Invoking App Install function ")$($functionName)"
$command = "$($functionName)$(" -App")"
$error = Invoke-Command -ScriptBlock { Invoke-Expression -Command $command} -ArgumentList $app
}
else
{
XtrLog -Level FATAL -FunctionName $MyInvocation.MyCommand -Msg "$("App Install Function " )$($functionName)$(" not found. See App name (e.g.'XtrInstall-Aplication')")"
return $true
}
}
}
else
{
XtrLog -Level WARN -FunctionName $MyInvocation.MyCommand -Msg "No Apps detected in Config file."
$error=$true
}
}
catch
{
XtrLog -Level FATAL -FunctionName $MyInvocation.MyCommand -Msg $_.Exception.Message
$error=$true
}
return $error
}
我调用的函数是:
function global:XtrInstall-Filesite()
{
Param(
[Parameter(Mandatory=$true)]
[Xml.XmlElement]$App
)
//DO STUFF
}
如何按原样传递参数?
不需要在 字符串 中构建(部分)命令并使用 Invoke-Expression
,甚至 Invoke-Command
.
请尝试以下操作:
$error = & $functionName -App $app
&
,PowerShell 的 call operator,可用于调用其 name 存储在 variable[=29] 中的任何命令=].
- (您还需要它来调用外部实用程序,其路径必须 引用 因为包含空格或其他具有特殊含义的字符;例如,
& 'c:\path\to\some folder\some.exe'
).
我正在将一个 XML 节点导入变量 XmlInstallNode,然后动态构建我要调用的函数。
如果我直接通过函数名称调用函数,一切都很好,但是如果在调用命令中使用 $functionName 调用它,那么参数 -App - 被转换为字符串,而它应该是 System.Xml.XmlLinkedNode。我已经尝试转换它并使用 Invoke-Expressions 和 Invoke-Command 的不同方法但没有成功...
我收到这个错误,这有点道理: 无法处理参数 'App' 的参数转换。无法将类型 "System.String" 的“$app”值转换为类型 "System.Xml.XmlElement"
function global:XtrInstall{
try
{
$error=$false
XtrLog -Level INFO -FunctionName $MyInvocation.MyCommand -Msg "Installing Apps..."
XtrLog -Level DEBUG -FunctionName $MyInvocation.MyCommand -Msg "Getting available Apps from config file."
$XmlInstallNode=XtrGet-XmlInstall
if($XmlInstallNode.Apps)
{
foreach($app in $XmlInstallNode.apps.app)
{
$functionName = "$("XtrInstall-")$($app.Name)"
XtrLog -Level DEBUG -FunctionName $MyInvocation.MyCommand -Msg "$("Building function name: ")$($functionName)"
if (Get-Command $functionName -errorAction SilentlyContinue)
{
XtrLog -Level DEBUG -FunctionName $MyInvocation.MyCommand -Msg "$("Invoking App Install function ")$($functionName)"
$command = "$($functionName)$(" -App")"
$error = Invoke-Command -ScriptBlock { Invoke-Expression -Command $command} -ArgumentList $app
}
else
{
XtrLog -Level FATAL -FunctionName $MyInvocation.MyCommand -Msg "$("App Install Function " )$($functionName)$(" not found. See App name (e.g.'XtrInstall-Aplication')")"
return $true
}
}
}
else
{
XtrLog -Level WARN -FunctionName $MyInvocation.MyCommand -Msg "No Apps detected in Config file."
$error=$true
}
}
catch
{
XtrLog -Level FATAL -FunctionName $MyInvocation.MyCommand -Msg $_.Exception.Message
$error=$true
}
return $error
}
我调用的函数是:
function global:XtrInstall-Filesite()
{
Param(
[Parameter(Mandatory=$true)]
[Xml.XmlElement]$App
)
//DO STUFF
}
如何按原样传递参数?
不需要在 字符串 中构建(部分)命令并使用 Invoke-Expression
,甚至 Invoke-Command
.
请尝试以下操作:
$error = & $functionName -App $app
&
,PowerShell 的 call operator,可用于调用其 name 存储在 variable[=29] 中的任何命令=].- (您还需要它来调用外部实用程序,其路径必须 引用 因为包含空格或其他具有特殊含义的字符;例如,
& 'c:\path\to\some folder\some.exe'
).
- (您还需要它来调用外部实用程序,其路径必须 引用 因为包含空格或其他具有特殊含义的字符;例如,