Cuando utilizo otro objeto en .net-Framework en C #, puedo ahorrar mucho tipeo usando la directiva using.
using FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It;
...
var blurb = new Thingamabob();
...
Entonces, ¿hay alguna forma en Powershell de hacer algo similar? Estoy accediendo a muchos objetos .net y no estoy contento de tener que escribir
$blurb = new-object FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It.Thingamabob;
todo el tiempo.
.net
powershell
powershell-2.0
froh42
fuente
fuente
using
declaración. Puede utilizar esto para espacios de nombres .net o módulos (que es una de las únicas formas de importar clases personalizadas). La sintaxis esusing namespace Name.Space.Here
orusing module C:\Path\to\manifest
. El único requisito es que esté antes de cualquier otra declaración en su guión (incluso el bloque param)Respuestas:
PowerShell 5.0 (incluido en WMF5 o Windows 10 en adelante) agrega la
using namespace
construcción al lenguaje. Puedes usarlo en tu script así:#Require -Version 5.0 using namespace FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It $blurb = [Thingamabob]::new()
(
#Require
No es necesario utilizar la declaración de la primera líneausing namespace
, pero evitará que el script se ejecute en PS 4.0 y en versiones anteriores, dondeusing namespace
hay un error de sintaxis).fuente
Realmente no hay nada en el nivel del espacio de nombres como eso. A menudo asigno tipos de uso común a las variables y luego las instanciado:
$thingtype = [FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It.Thingamabob]; $blurb = New-Object $thingtype.FullName
Probablemente no valga la pena si el tipo no se usa repetidamente, pero creo que es lo mejor que puede hacer.
fuente
$ns = [System.Runtime.InteropServices.Marshal]
entonces puedes$ns::PtrToStringAuto($ns::SecureStringToBSTR($ss))
.([pscredential]::new('+',$ss)).GetNetworkCredential().Password
Consulte esta publicación de blog de hace un par de años: http://blogs.msdn.com/richardb/archive/2007/02/21/add-types-ps1-poor-man-s-using-for-powershell.aspx
Aquí está
add-types.ps1
, extraído de ese artículo: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 } } }
Y, para usarlo:
RICBERG470> $tfs | add-types "Microsoft.TeamFoundation.VersionControl.Client" RICBERG470> $itemSpec = new-object $tfs.itemspec("$/foo", $tfs.RecursionType::none)
Básicamente, lo que hago es rastrear el ensamblado en busca de tipos no triviales, luego escribir un "constructor" que use Add-Member y agregarlos (de forma estructurada) a los objetos que me interesan.
Vea también esta publicación de seguimiento: http://richardberg.net/blog/?p=38
fuente
New-Object PSObject
.esto es solo una broma, broma ...
$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
fuente
try..catch
como una biblioteca , como Haskell y IIRC Clojure.Aquí hay un código que funciona en PowerShell 2.0 para agregar alias de tipo. Pero el problema es que no tiene alcance. Con un poco de trabajo adicional, podría "anular la importación" de los espacios de nombres, pero esto debería ayudarlo a comenzar bien.
############################################################################## #.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) } } } }
fuente
Si solo necesita crear una instancia de su tipo, puede almacenar el nombre del espacio de nombres largo en una cadena:
$st = "System.Text" $sb = New-Object "$st.StringBuilder"
No es tan poderoso como la
using
directiva en C #, pero al menos es muy fácil de usar.fuente
Gracias a todos por sus comentarios. He marcado la contribución de Richard Berg como una respuesta, porque se parece más a lo que estoy buscando.
Todas sus respuestas me llevaron por el camino que parece más prometedor: en su publicación de blog, Keith Dahlby propone un comando Get-Type que permite una fácil construcción de tipos para métodos genéricos.
Creo que no hay razón para no extender esto para buscar también un tipo en una ruta predefinida de ensamblados.
Descargo de responsabilidad: no lo he construido, todavía ...
Así es como se podría usar:
$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()
Esto resultaría en una buena lista genérica de Thingamabob. Por supuesto, terminaría todo sin la definición de la ruta en otra función de utilidad. El get-type extendido incluiría un paso para resolver cualquier tipo dado contra la ruta.
fuente
#Requires -Version 5 using namespace System.Management.Automation.Host #using module
fuente
Me doy cuenta de que esta es una publicación antigua, pero estaba buscando lo mismo y encontré esto: http://weblogs.asp.net/adweigert/powershell-adding-the-using-statement
Editar: supongo que debería especificar que le permite usar la sintaxis familiar de ...
using ($x = $y) { ... }
fuente