Equivalent to C#'s “using” keyword in powershell?

前端 未结 9 1767
臣服心动
臣服心动 2020-12-04 14:13

When I use another object in the .net-Framework in C# I can save a lot of typing by using the using directive.

using FooCompany.Bar.Qux.Assembly.With.Ridicul         


        
相关标签:
9条回答
  • 2020-12-04 14:43

    There's really nothing at the namespace level like that. I often assign commonly used types to variables and then instantiate them:

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

    Probably not worth it if the type won't be used repeatedly, but I believe it's the best you can do.

    0 讨论(0)
  • 2020-12-04 14:47
    #Requires -Version 5
    using namespace System.Management.Automation.Host
    #using module
    
    0 讨论(0)
  • 2020-12-04 14:53

    Here's some code that works in PowerShell 2.0 to add type aliases. But the problem is that it is not scoped. With some extra work you could "un-import" the namespaces, but this should get you off to a good start.

    ##############################################################################
    #.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)
                }
            }
    
        }
    
    }
    
    0 讨论(0)
  • 2020-12-04 14:54

    PowerShell 5.0 (included in WMF5 or Windows 10 and up), adds the using namespace construct to the language. You can use it in your script like so:

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

    (The #Require statement on the first line is not necessary to use using namespace, but it will prevent the script from running in PS 4.0 and below where using namespace is a syntax error.)

    0 讨论(0)
  • 2020-12-04 14:54

    this is just a joke, joke...

    $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
    
    0 讨论(0)
  • 2020-12-04 14:54

    Thanks everybody for your input. I've marked Richard Berg's contribution as an answer, because it most closely resembles what I'm looking for.

    All your answers brought me on the track that seems most promising: In his blog post Keith Dahlby proposes a Get-Type commandlet that allows easy consutruction of types for generic methods.

    I think there is no reason against exetending this to also search through a predefined path of assemblies for a type.

    Disclaimer: I haven't built that -- yet ...

    Here is how one could use it:

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

    This would result in a nice generic List of Thingamabob. Of course I'd wrap up everthing sans the path definition in just another utility function. The extended get-type would include a step to resolve any given type agains the path.

    0 讨论(0)
提交回复
热议问题