Вопрос по .net, powershell-v2.0, powershell – Эквивалентно тому, что C # использует ключевое слово в powershell?

67

Когда я использую другой объект в .net-Framework в C #, я могу сэкономить много текста, используя директиву using.

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

...


  var blurb = new Thingamabob();

...
</code>

Так есть ли в Powershell способ сделать что-то похожее? Я получаю доступ ко многим объектам .net и не рад тому, что мне нужно набрать

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

все время.

Я знаю, что это старый вопрос, но PowerShell 5 представилusing заявление. Вы можете использовать это для пространств имен .net или модулей (это один из немногих способов импорта пользовательских классов). Синтаксисusing namespace Name.Space.Here или жеusing module C:\Path\to\manifest, Единственное требование состоит в том, чтобы он предшествовал любым другим операторам в вашем скрипте (даже блоку param) TheIncorrigible1

Ваш Ответ

9   ответов
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)
            }
        }

    }

}
Джош, спасибо, я еще не смотрел на расширение типов ускорителей. Это очень интересно, я думаю, я немного поиграюсь с этим. froh42
Это удобно, но используйте его с осторожностью. Ничего хуже, чем написание сценария, который не работает на чужой машине. По этой причине я никогда не помещал эти ускорители в свой профиль. Во всяком случае, я помещу их в верхнюю часть скрипта таким образом, чтобы он сразу же потерпел неудачу в Add-TypeAccelerator.
7

$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
@ProgrammerPaul (по сравнению с функциональными языками), лол, просто читал это, оборачивая F # lib (DSL Parser через FParsec). Я знаю / люблю Haskell, Clojure, Scala и до сих пор не могу удержать комментарий. Вот оно: Возможно, попробуйте какой-нибудь действительно объектно-ориентированный язык, например Smalltalk - он реализует If / Else как библиотеку ;-)))
Может ли кто-нибудь объяснить двойной `` 1 в типе, который мне трудно найти?
@ProgrammerPaul Если вы находите это забавным, попробуйте функциональный язык - некоторые из них реализуютtry..catch какlibrary, включая Haskell и IIRC Clojure.
Это будет эквивалентно оператору C # using, а не директиве using.
Мне нравится, как это выглядит. Если бы вы взяли на себя обязательство, это кажется мне довольно элегантным решением. Гибкость PowerShell при создании нового синтаксиса меня очень радует.
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

Кажется, что нужно использовать имя сборки (например, mscorlib) вместо имени типа (например, System.IO.Path).
Если у вас нет объекта, чтобы передать его функции, вы можете создать его, используяNew-Object PSObject.
2

вета, потому что он наиболее близко напоминает то, что я ищу.

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

54

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

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

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

Иногда мне нужно преобразовать SecureStrings обратно в обычный текст. Полезно следующее:$ns = [System.Runtime.InteropServices.Marshal] тогда ты можешь$ns::PtrToStringAuto($ns::SecureStringToBSTR($ss)).
Примечание для тех, кто ищет ответ с самым высоким рейтингом: PowerShell 5.0 исправляет это.
5

вы можете сохранить имя длинного пространства имен в строке:

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

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

-2

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

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

using ($x = $y) { ... }
Туш & APOS ;. Я неправильно понял вопрос.
Это будет эквивалентно оператору C # using, а не директиве using.
30

using namespace построить на язык. Вы можете использовать его в своем скрипте так:

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

(The#Require оператор в первой строке не обязательно использоватьusing namespace, но это предотвратит запуск скрипта в PS 4.0 и ниже, гдеusing namespace это синтаксическая ошибка.)

0
#Requires -Version 5
using namespace System.Management.Automation.Host
#using module

Похожие вопросы