PowerShellでのC#の「using」キーワードに相当しますか?


80

C#の.net-Frameworkで別のオブジェクトを使用する場合、usingディレクティブを使用することで多くの入力を節約できます。

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

...


  var blurb = new Thingamabob();

...

では、Powershellに同様のことを行う方法はありますか?たくさんの.netオブジェクトにアクセスしているので、入力する必要がありません。

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

いつも。


1
これは古い質問ですが、PowerShell5でこのusingステートメントが導入されました。これは、.net名前空間またはモジュール(カスタムクラスをインポートする唯一の方法の1つ)に利用できます。構文はusing namespace Name.Space.Hereまたはusing module C:\Path\to\manifestです。唯一の要件は、スクリプト内の他のステートメント(paramブロックも含む)の前にあることです
Maximilian Burszley 2018年

回答:


43

PowerShell 5.0(WMF5またはWindows 10以降に含まれています)はusing namespace、言語に構成を追加します。次のようにスクリプトで使用できます。

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

#Require最初の行のステートメントを使用する必要はありませんusing namespaceが、PS 4.0以下でスクリプトを実行できなくなりusing namespaceます。構文エラーが発生します。)


1
その#Requireステートメントは知っておくと便利なことです。ありがとう。
SimonTewsi19年

これは一般的なスクリプトで機能しますが、インラインスクリプトを使用したAzure DevOps PowerShellタスクでは、usingが最初のステートメントではないと述べています。
Andrii

57

名前空間レベルでは、そのようなものは実際にはありません。私はよく使用される型を変数に割り当ててからインスタンス化します。

$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))ます。
petrsnd 2016年

1
最高評価の回答を見ている人への注意:PowerShell5.0はこれを修正します。
デイブマークル2017

@petrsndまたは使用([pscredential]::new('+',$ss)).GetNetworkCredential().Password
ニコラ・Melay

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


タイプ名(System.IO.Pathなど)の代わりにアセンブリ名(mscorlibなど)を使用する必要があるようです。
Micha Wiedenmann

関数に渡すオブジェクトがない場合は、を使用してオブジェクトを作成できますNew-Object PSObject
Micha Wiedenmann

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

誰かがダブル「タイプの1、私は検索するのが難しいと思っています。
ピート

これは、usingディレクティブではなく、C#usingステートメントと同等です。
パウロモルガド2015年

私はこれが見える方法が好きです。あなたがそれにコミットするならば、これは私にとってかなりエレガントな解決策のように思えます。新しい構文を作成する際のPowerShellの柔軟性は、私を非常に満足させます。
プログラマーPaul

@ProgrammerPaul面白いと思ったら、関数型言語を試してみてください。HaskellやIIRC Clojureなどtry..catchライブラリとして実装されているものもあります。
jpaugh 2016年

@ProgrammerPaul(wrt。関数型言語)笑、F#lib(FParsec経由のDSLパーサー)をラップしながらこれを読んでください。Haskell、Clojure、Scalaを知っている/好きですが、それでもコメントを保持できません。ここに来る:Smalltalkのような本当にオブジェクト指向言語を試してみてください-それはライブラリとしてIf / Elseを実装します;-)))
Miloslav Raus 2018

5

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

    }

}

Josh、ありがとうございます。まだ型アクセラレータの拡張を検討していませんでした。これは非常に興味深いです、私はそれで少し遊んでみようと思います。
froh42 2009年

便利ですが、注意して使用してください。他の人のマシンで動作しないスクリプトを書くことほど悪いことはありません。そのため、これらのアクセラレータをプロファイルに含めることはありません。どちらかといえば、スクリプトの先頭に配置して、Add-TypeAcceleratorですぐに失敗するようにします。
Josh

5

タイプのインスタンスを作成する必要があるだけの場合は、長い名前空間の名前を文字列に格納できます。

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

usingC#のディレクティブほど強力ではありませんが、少なくとも非常に使いやすいです。


2

ご意見ありがとうございます。私が探しているものに最もよく似ているので、私はリチャード・バーグの貢献を答えとしてマークしました。

あなたのすべての答えは、私を最も有望と思われる軌道に乗せました:彼のブログ投稿で Keith Dahlbyは、ジェネリックメソッドの型を簡単に作成できる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-typeには、パスに対して特定の型を解決するステップが含まれます。



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.