在Powershell 2中声明第三方程序集类型的通用列表

时间:2017-09-03 23:32:37

标签: .net powershell

我正在尝试在Powershell 2.0中创建Collections.Generic.List类型的新Amazon.Cloudwatch.Model.Dimensions对象。

我可以使用:

成功创建Amazon.Cloudwatch.Model.Dimensions个对象
> $dimension = New-Object Amazon.Cloudwatch.Model.Dimensions

我可以使用:

创建Collections.Generic.List类型为string的对象
> $list = New-Object Collections.Generic.List[string]

但是,当我尝试创建Collections.Generic.List类型的Amazon.Cloudwatch.Model.Dimensions对象时,我收到以下错误:

> $list = New-Object Collections.Generic.List[Amazon.Cloudwatch.Model.Dimension]

New-Object : Cannot find type 
[Collections.Generic.List[Amazon.Cloudwatch.Model.Dimension]]: make sure the assembly containing this type is loaded.
At line:1 char:19
+ $list = New-Object <<<<  
Collections.Generic.List[Amazon.Cloudwatch.Model.Dimension]
    + CategoryInfo          : InvalidType: (:) [New-Object], 
PSArgumentException
    + FullyQualifiedErrorId : 
TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand

同样的声明适用于Powershell 3.0,因此看起来这是由Powershell 2.0泛型查找程序集的方式引起的。根据{{​​3}},Powershell 2.0中存在一个可能与之相关的错误:

  

但是,有一个不幸的问题。在PowerShell 2.0中,将BCL和第三方类型混合并匹配为类型参数时会出现错误。后者需要装配合格:

# broken over two lines for clarity with backtick escape
$o = new-object ('collections.generic.dictionary[[{0}],[{1}]]' -f `
    [type1].fullname, [type2].fullname)
  

希望这会有所帮助。在PowerShell 3.0中,这已得到修复。

我(有点)试图这样做没有成功。

并且another SO answer建议更多地使用以下方式对程序集进行限定:

  

解决方案是为通用参数类型指定完全限定的程序集名称。这非常难看,但有效:

$bar = new-object "System.Collections.Generic.Dictionary``2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"

我试过了:

> $list = New-Object "System.Collections.Generic.List``1[[Amazon.CloudWatch.Model.Dimension, AWSSDK.CloudWatch, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604]]"

也没有成功。

> $list = New-Object "System.Collections.Generic.List``1[[Amazon.CloudWatch.Model.Dimension, AWSSDK.CloudWatch, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604]]"
New-Object : Cannot find type 
[System.Collections.Generic.List`1[[Amazon.CloudWatch.Model.Dimension, AWSSDK.CloudWatch, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604]]]: make sure the assembly containing this type is loaded.
At line:1 char:22
+ $dimlist = New-Object <<<<  
"System.Collections.Generic.List``1[[Amazon.CloudWatch.Model.Dimension, AWSSDK.CloudWatch, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604]]"
    + CategoryInfo          : InvalidType: (:) [New-Object], PSArgumentException
    + FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand

我们非常感谢任何建议。

注意:Amazon.Cloudwatch.Model.Dimensions来自another SO answer

3 个答案:

答案 0 :(得分:2)

这是在PowerShell版本2.0中进行了测试,使用了您在问题中链接到的帖子的想法组合:

Add-Type -Path "C:\Program Files (x86)\AWS SDK for .NET\bin\Net35\AWSSDK.CloudWatch.dll"
$o = "System.Collections.Generic.List``1" -as "Type"
$o = $o.MakeGenericType("Amazon.Cloudwatch.Model.Dimension" -as "Type")
$list = [Activator]::CreateInstance($o)

$list.gettype() | select UnderlyingSystemType

UnderlyingSystemType
--------------------
System.Collections.Generic.List`1[Amazon.CloudWatch.Model.Dimension]

答案 1 :(得分:1)

我无法对端到端进行测试。当然,我可以确认这个问题。

但是,我在想,为什么不在声明列表类型并查看是否过时时尝试更通用。

#Add-Type -Path "C:\Program Files (x86)\AWS SDK for .NET\bin\Net35\AWSSDK.CloudWatch.dll"
$list = New-Object Collections.Generic.List[System.Object]
$d = $dims = New-Object Amazon.Cloudwatch.Model.Dimension
$d.name = "AutoScalingGroup"
$d.value = "xy"
$list.Add($dim)
$list | Get-Member

这是截图。想法?

Else statement only

答案 2 :(得分:0)

$list = [Activator]::CreateInstance([System.Collections.Generic.List`1].MakeGenericType([Amazon.CloudWatch.Model.Dimension, AWSSDK.CloudWatch, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604]))

当然,您需要先加载程序集或将其添加到GAC。在我的测试中,我从C:\ Program Files(x86)\ AWS SDK for .NET \ bin \ Net45加载了所有程序集。

foreach ($file in Get-ChildItem -Path 'C:\Program Files (x86)\AWS SDK for .NET\bin\Net35\' -Filter '*.dll')
{
    [Reflection.Assembly]::LoadFile($file.FullName) | Out-Null
}