【问题标题】:Why does powershell sometimes pass PSObject (instead of the base object) to .Net code?为什么 powershell 有时会将 PSObject(而不是基础对象)传递给 .Net 代码?
【发布时间】:2014-03-05 08:24:30
【问题描述】:

我发现在某些情况下,当作为参数传递给 .Net 代码时,powershell 2.0 正在传递包含 PSObjects 的 Object[] 数组——而不是真正包含的类型。我认为这是一个 powershell 2.0 错误,但我找不到任何提及。

$Source = @" 
public static class DotNetTypeInfo
{ 
    public static string TypeOfNthElement(object[] oa, int n)
    {
        return oa[n].GetType().ToString();
    }    
} 
"@ 
Add-Type -TypeDefinition $Source -Language CSharp  

$h = @{}
$h.foo = "bar"
#$h["foo"] = "bar" # uncomment this to fix! (Why?)

$testdata = @($h) # To .net, passed Object[] containing PSObject, not Hashtable!

# other examples that behave similarly badly - uncomment to try
$a = (1,2) # should result in an arry of System.Int32
function getA() { $a } # uncaptured value returned
function getB() { return $a } # explicit return
# $testdata = $a    # this works fine
# $testdata  = getA # also fine
# $testdata  = getB # To .net, passed Object[] containing PSObject, not Int32!

Write-Host "From powershell"
'  $testdata[0].GetType()         ' + $testdata[0].GetType().ToString()
Write-Host "From .Net"
'  TypeOfNthElement($testdata,0)  ' + [DotNetTypeInfo]::TypeOfNthElement($testdata,0)

打印出来:

From powershell
  $testdata[0].GetType()         System.Collections.Hashtable
From .Net
  TypeOfNthElement($testdata,0)  System.Management.Automation.PSObject

最后一行非常令人惊讶; C# 代码正在接收包含PSObjectObject[],而不是包含HashtableObject[]。这使得无法与不期望 PSObject 的现有 .Net 库一起使用。

奇怪的是,如果我使用 $h["foo"] = "bar" 而不是 $h.foo = "bar",我可以解决这个问题。

我还看到了类似的效果,具体取决于您从函数返回值的方式 - 取消注释 getAgetB 示例以尝试。

应要求 - 从 $psversiontable 中选择的亮点,为简洁而编辑:

Key   : CLRVersion, Value : 2.0.50727.5472
Key   : BuildVersion, Value : 6.1.7601.17514
Key   : PSVersion, Value : 2.0
Key   : PSCompatibleVersions, Value : {1.0, 2.0}
Key   : SerializationVersion, Value : 1.1.0.1

我可以在 XP、Win7 和 Windows Server 2008 R2 上使用 powershell 2.0 复制此问题

【问题讨论】:

  • 如果你还在看 - 我能解释一下投反对票的原因吗?
  • 我找不到 PS 2 是否仍在修补/维护,但我有 submitted a bug report

标签: .net powershell powershell-2.0


【解决方案1】:

我在带有 PowerShell V2.0 的 W2K3 Box 上尝试了您的代码,第三次测试返回了["hello","world"]

如果getdata3 看起来像这样,我会收到你的错误:

function getdata3()
{
  $a
  return " "
}

所以我的结论是您的脚本代码中有一些“隐藏”字符,这些字符在复制/过去这个问题时丢失了。

关于更多:你能在你的 PowerShell 上给出 $psversiontable 的值吗?

【讨论】:

  • 你在源代码中寻找隐藏的字符吗?
  • 我已将它按原样 from 粘贴到脚本中,同样的问题。所以我这里没有你没有的东西。
  • 您的函数也不应该引发该错误(没有循环引用)。我在使用此功能时遇到了与您相同的问题,如果我删除 return 关键字,它就会消失。所以我认为你可能已经复制了这个问题。
  • 用大量新信息改进了 Q。
猜你喜欢
  • 1970-01-01
  • 2013-05-18
  • 2022-01-06
  • 2020-06-22
  • 2015-01-14
  • 1970-01-01
  • 1970-01-01
  • 2021-01-29
  • 2022-01-06
相关资源
最近更新 更多