Question

Lorsque j'utilise un autre objet dans le trame .NET en C #, je peux enregistrer beaucoup de saisie en utilisant la directive d'utilisation.

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

...


  var blurb = new Thingamabob();

...

Alors, y a-t-il un moyen à PowerShell de faire quelque chose de similaire? J'accès à beaucoup d'objets .NET et je ne suis pas content de devoir taper

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

tout le temps.

Était-ce utile?

La solution

PowerShell 5.0 (inclus dans WMF5 ou Windows 10 et plus), ajoute le using namespace construire dans la langue. Vous pouvez l'utiliser dans votre script comme tel:

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

(La #Require La déclaration sur la première ligne n'est pas nécessaire pour utiliser using namespace, mais cela empêchera le script de s'exécuter en PS 4.0 et en dessous d'où using namespace est une erreur de syntaxe.)

Autres conseils

Il n'y a vraiment rien au niveau de l'espace de noms comme ça. J'attribue souvent des types couramment utilisés aux variables, puis je les instanciers:

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

Cela ne vaut probablement pas la peine si le type ne sera pas utilisé à plusieurs reprises, mais je crois que c'est le meilleur que vous puissiez faire.

Consultez cet article de blog il y a quelques années: http://blogs.msdn.com/richardb/archive/2007/02/21/add-types-ps1-poor-man-s-using-for-powershell.aspx

Voici add-types.ps1, extrait de cet article:

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

Et, pour l'utiliser:

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

Fondamentalement, ce que je fais, c'est ramper l'assemblage pour les types non triviaux, puis écrire un "constructeur" qui utilise des Add-Member, ajoutez-les (de manière structurée) aux objets qui m'intéresse.

Voir aussi ce post de suivi: http://richardberg.net/blog/?p=38

C'est juste une blague, blague ...

$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

Voici un code qui fonctionne dans PowerShell 2.0 pour ajouter des alias de type. Mais le problème est qu'il n'est pas étendu. Avec un peu de travail supplémentaire, vous pourriez "vous détendre" les espaces de noms, mais cela devrait vous faire bien démarrer.

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

    }

}

Si vous avez juste besoin de créer une instance de votre type, vous pouvez stocker le nom de l'espace de noms long dans une chaîne:

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

Ce n'est pas aussi puissant que le using Directive en C #, mais au moins c'est très facile à utiliser.

Merci à tous pour votre contribution. J'ai marqué la contribution de Richard Berg en tant que réponse, car elle ressemble le plus à ce que je recherche.

Toutes vos réponses m'ont amené sur la piste qui semble la plus prometteuse: dans Son article de blog Keith Dahlby propose un commandement de type Get-Get qui permet une consutation facile de types pour les méthodes génériques.

Je pense qu'il n'y a aucune raison contre l'exedoir pour rechercher également un chemin prédéfini des assemblages pour un type.

Avertissement: je n'ai pas encore construit cela - encore ...

Voici comment on pourrait l'utiliser:

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

Cela entraînerait une belle liste générique de ThingAmabob. Bien sûr, je terminerais tout sans la définition du chemin dans une autre fonction d'utilité. Le type Get prolongé comprendrait une étape pour résoudre un type donné à nouveau le chemin.

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

Je me rends compte que c'est un vieux post, mais je cherchais la même chose et je suis tombé sur ceci: http://weblogs.asp.net/adweigert/powershell-adding-the-using-statement

Edit: je suppose que je dois spécifier qu'il vous permet d'utiliser la syntaxe familière de ...

using ($x = $y) { ... }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top