Эквивалентно тому, что C # использует ключевое слово в powershell? - PullRequest
71 голосов
/ 26 июня 2009

Когда я использую другой объект в .net-Framework в C #, я могу сэкономить много печатания с помощью директивы 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;

все время.

Ответы [ 9 ]

55 голосов
/ 26 июня 2009

Нет ничего такого на уровне пространства имен. Я часто присваиваю переменные часто используемые типы, а затем создаю их экземпляры:

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

Вероятно, не стоит, если тип не будет использоваться повторно, но я считаю, что это лучшее, что вы можете сделать.

35 голосов
/ 14 июля 2016

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 - синтаксическая ошибка.)

12 голосов
/ 26 июня 2009

Ознакомьтесь с этой записью в блоге пару лет назад: 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

7 голосов
/ 26 июня 2009

это просто шутка, шутка ...

$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
5 голосов
/ 02 ноября 2013

Если вам просто нужно создать экземпляр вашего типа, вы можете сохранить имя длинного пространства имен в строке:

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

Он не такой мощный, как директива using в C #, но, по крайней мере, очень прост в использовании.

5 голосов
/ 16 ноября 2009

Вот код, который работает в 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)
            }
        }

    }

}
2 голосов
/ 28 июня 2009

Спасибо всем за ваш вклад. Я отметил вклад Ричарда Берга как ответ, потому что он больше всего напоминает то, что я ищу.

Все ваши ответы привели меня на путь, который кажется наиболее многообещающим: в его посте в блоге Кейт Дальби предлагает командлет 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()

Это приведет к хорошему обобщенному списку тингамабобов. Конечно, я бы обернул все без определения пути в еще одну служебную функцию. Расширенный get-тип будет включать в себя шаг для разрешения любого заданного типа по пути.

0 голосов
/ 05 марта 2017
#Requires -Version 5
using namespace System.Management.Automation.Host
#using module
0 голосов
/ 24 сентября 2015

Я понимаю, что это старый пост, но я искал то же самое и наткнулся на это: http://weblogs.asp.net/adweigert/powershell-adding-the-using-statement

Редактировать: Полагаю, мне следует указать, что он позволяет использовать знакомый синтаксис ...

using ($x = $y) { ... }
...