Pergunta

Quando eu uso um outro objeto .net-Framework em C# eu posso salvar um monte de digitação usando a diretiva usando.

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

...


  var blurb = new Thingamabob();

...

Assim é que existe uma maneira em Powershell para fazer algo semelhante?Estou acessando um monte de .net objetos e não estou feliz de ter que digitar

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

todo o tempo.

Foi útil?

Solução

PowerShell 5.0 (incluído no WMF5 ou Windows 10 ou mais), adiciona o using namespace construir para o idioma. Você pode usá -lo no seu script como assim:

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

(O #Require A declaração na primeira linha não é necessária para usar using namespace, mas impedirá que o script seja executado no PS 4.0 e abaixo de onde using namespace é um erro de sintaxe.)

Outras dicas

Realmente não há nada no nível do espaço de nomes assim.Eu, muitas vezes, atribuir tipos comumente usados para variáveis e, em seguida, instanciá-los:

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

Provavelmente não vale a pena se o tipo não vai ser usada várias vezes, mas eu acredito que é o melhor que você pode fazer.

Confira esta postagem do blog de alguns anos atrás: http://blogs.msdn.com/richardb/archive/2007/02/21/add-types-ps1-poor-man-s-using-for-powershell.aspx

Aqui está add-types.ps1, extraído desse artigo:

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
        }
    }
}

E, para usá -lo:

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

Basicamente, o que eu faço é rastejar a montagem para tipos não triviais e, em seguida, escreva um "construtor" que usa add-MEMBER, adicione-os (de maneira estruturada) aos objetos com os quais me preocupo.

Veja também este post de acompanhamento: http://richardberg.net/blog/?p=38

Isso é apenas uma piada, piada ...

$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

Aqui está algum código que funciona no PowerShell 2.0 para adicionar aliases de tipo. Mas o problema é que ele não está escopo. Com algum trabalho extra, você pode "não ter" os espaços para nome, mas isso deve começar bem.

##############################################################################
#.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)
            }
        }

    }

}

Se você só precisar criar uma instância do seu tipo, poderá armazenar o nome do espaço para nome longo em uma string:

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

Não é tão poderoso quanto o using Diretiva em C#, mas pelo menos é muito fácil de usar.

Obrigado a todos por sua contribuição. Marquei a contribuição de Richard Berg como resposta, porque se assemelha mais ao que estou procurando.

Todas as suas respostas me trouxeram na pista que parece mais promissor: em sua postagem no blog Keith Dahlby propõe um comando get-type que permite fácil construção de tipos para métodos genéricos.

Eu acho que não há razão para excluir isso para pesquisar também um caminho predefinido de montagens para um tipo.

Isenção de responsabilidade: eu não construí isso - ainda ...

Aqui está como alguém poderia usá -lo:

$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()

Isso resultaria em uma boa lista genérica de Thingamabob. É claro que eu encerraria tudo sem a definição de caminho em apenas mais uma função de utilidade. O tipo GET estendido incluiria uma etapa para resolver qualquer tipo de tipo novamente o caminho.

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

Sei que este é um post antigo, mas eu estava procurando a mesma coisa e me deparei com isso: http://weblogs.asp.net/adweigert/powershell-adding-the-using statement

EDIT: Suponho que devo especificar que ele permite que você use a sintaxe familiar de ...

using ($x = $y) { ... }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top