83

当我在 C# 的 .net-Framework 中使用另一个对象时,我可以通过使用 using 指令来节省大量输入。

using FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It;

...


  var blurb = new Thingamabob();

...

那么Powershell中有没有办法做类似的事情呢?我正在访问很多 .net 对象,但不满意必须输入

 $blurb = new-object FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It.Thingamabob;

每时每刻。

4

9 回答 9

59

在命名空间级别真的没有这样的东西。我经常将常用类型分配给变量,然后实例化它们:

$thingtype = [FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It.Thingamabob];
$blurb = New-Object $thingtype.FullName

如果该类型不会重复使用,可能不值得,但我相信这是你能做的最好的。

于 2009-06-26T13:02:34.313 回答
48

PowerShell 5.0(包含在 WMF5 或 Windows 10 及更高版本中)将using namespace结构添加到语言中。您可以像这样在脚本中使用它:

#Require -Version 5.0
using namespace FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It
$blurb = [Thingamabob]::new()

#Require第一行的语句不是必须使用using namespace,但它会阻止脚本在 PS 4.0 及以下using namespace的语法错误处运行。)

于 2016-07-14T04:37:30.667 回答
12

查看几年前的这篇博文:http: //blogs.msdn.com/richardb/archive/2007/02/21/add-types-ps1-poor-man-s-using-for-powershell.aspx

这是add-types.ps1,摘自那篇文章:

param(
    [string] $assemblyName = $(throw 'assemblyName is required'),
    [object] $object
)

process {
    if ($_) {
        $object = $_
    }

    if (! $object) {
        throw 'must pass an -object parameter or pipe one in'
    }

    # load the required dll
    $assembly = [System.Reflection.Assembly]::LoadWithPartialName($assemblyName)

    # add each type as a member property
    $assembly.GetTypes() | 
    where {$_.ispublic -and !$_.IsSubclassOf( [Exception] ) -and $_.name -notmatch "event"} | 
    foreach { 
        # avoid error messages in case it already exists
        if (! ($object | get-member $_.name)) {
            add-member noteproperty $_.name $_ -inputobject $object
        }
    }
}

并且,要使用它:

RICBERG470> $tfs | add-types "Microsoft.TeamFoundation.VersionControl.Client"
RICBERG470> $itemSpec = new-object $tfs.itemspec("$/foo", $tfs.RecursionType::none)

基本上我所做的是抓取非平凡类型的程序集,然后编写一个使用 Add-Member 的“构造函数”将它们(以结构化方式)添加到我关心的对象中。

另请参阅此后续帖子:http ://richardberg.net/blog/?p=38

于 2009-06-26T14:49:43.863 回答
8

这只是个玩笑,玩笑……

$fullnames = New-Object ( [System.Collections.Generic.List``1].MakeGenericType( [String]) );

function using ( $name ) { 
foreach ( $type in [Reflection.Assembly]::LoadWithPartialName($name).GetTypes() )
    {
        $fullnames.Add($type.fullname);
    }
}

function new ( $name ) {
    $fullname = $fullnames -like "*.$name";
    return , (New-Object $fullname[0]);
}

using System.Windows.Forms
using FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It
$a = new button
$b = new Thingamabob
于 2009-06-26T15:16:39.020 回答
5

下面是一些在 PowerShell 2.0 中用于添加类型别名的代码。但问题是它没有作用域。通过一些额外的工作,您可以“取消导入”名称空间,但这应该会让您有一个良好的开端。

##############################################################################
#.SYNOPSIS
# Add a type accelerator to the current session.
#
#.DESCRIPTION
# The Add-TypeAccelerator function allows you to add a simple type accelerator
# (like [regex]) for a longer type (like [System.Text.RegularExpressions.Regex]).
#
#.PARAMETER Name
# The short form accelerator should be just the name you want to use (without
# square brackets).
#
#.PARAMETER Type
# The type you want the accelerator to accelerate.
#
#.PARAMETER Force
# Overwrites any existing type alias.
#
#.EXAMPLE
# Add-TypeAccelerator List "System.Collections.Generic.List``1"
# $MyList = New-Object List[String]
##############################################################################
function Add-TypeAccelerator {

    [CmdletBinding()]
    param(

        [Parameter(Position=1,Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
        [String[]]$Name,

        [Parameter(Position=2,Mandatory=$true,ValueFromPipeline=$true)]
        [Type]$Type,

        [Parameter()]
        [Switch]$Force

    )

    process {

        $TypeAccelerators = [Type]::GetType('System.Management.Automation.TypeAccelerators')

        foreach ($a in $Name) {
            if ( $TypeAccelerators::Get.ContainsKey($a) ) {
                if ( $Force ) {
                    $TypeAccelerators::Remove($a) | Out-Null
                    $TypeAccelerators::Add($a,$Type)
                }
                elseif ( $Type -ne $TypeAccelerators::Get[$a] ) {
                    Write-Error "$a is already mapped to $($TypeAccelerators::Get[$a])"
                }
            }
            else {
                $TypeAccelerators::Add($a, $Type)
            }
        }

    }

}
于 2009-11-15T21:15:43.470 回答
5

如果您只需要创建您的类型的实例,您可以将长命名空间的名称存储在一个字符串中:

$st = "System.Text"
$sb = New-Object "$st.StringBuilder"

它不如usingC# 中的指令强大,但至少它非常易于使用。

于 2013-11-02T15:31:19.987 回答
2

谢谢大家的意见。我已将 Richard Berg 的贡献标记为答案,因为它与我正在寻找的最相似。

你所有的答案都让我走上了看起来最有希望的轨道:在他的博客文章中, Keith Dahlby 提出了一个 Get-Type 命令行开关,它允许为泛型方法轻松构造类型。

我认为没有理由反对扩展它来搜索预定义的程序集路径以查找类型。

免责声明:我还没有建立它——但......

以下是如何使用它:

$path = (System.Collections.Generic, FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It)

$type = get-type -Path $path List Thingamabob
$obj = new-object $type
$obj.GetType()

这将产生一个很好的 Thingamabob 通用列表。当然,我会在另一个实用程序函数中结束所有没有路径定义的事情。扩展的 get-type 将包括一个步骤,以根据路径解析任何给定类型。

于 2009-06-28T02:37:49.063 回答
0
#Requires -Version 5
using namespace System.Management.Automation.Host
#using module
于 2017-03-05T13:58:19.477 回答
-2

我意识到这是一篇旧帖子,但我正在寻找同样的东西并遇到了这个:http ://weblogs.asp.net/adweigert/powershell-adding-the-using-statement

编辑:我想我应该指定它允许您使用熟悉的语法...

using ($x = $y) { ... }
于 2015-09-24T20:19:55.623 回答