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;
항상.
답변
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
없지만 using namespace
구문 오류가있는 PS 4.0 이하에서는 스크립트가 실행 되지 않습니다 .)
답변
그런 네임 스페이스 수준에는 실제로 아무것도 없습니다. 자주 사용되는 유형을 변수에 할당 한 다음 인스턴스화합니다.
$thingtype = [FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It.Thingamabob];
$blurb = New-Object $thingtype.FullName
유형이 반복적으로 사용되지 않으면 아마도 그만한 가치가 없을 것입니다. 그러나 나는 그것이 당신이 할 수있는 최선이라고 생각합니다.
답변
몇 년 전 블로그 게시물을 확인하세요. 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
답변
이건 그냥 농담, 농담 …
$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
답변
다음은 유형 별칭을 추가하기 위해 PowerShell 2.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)
}
}
}
}
답변
유형의 인스턴스를 만들어야하는 경우 긴 네임 스페이스의 이름을 문자열에 저장할 수 있습니다.
$st = "System.Text"
$sb = New-Object "$st.StringBuilder"
using
C # 의 지시문 만큼 강력 하지는 않지만 적어도 사용하기는 매우 쉽습니다.
답변
귀하의 의견에 감사드립니다. Richard Berg의 기여는 제가 찾고있는 것과 가장 유사하기 때문에 답변으로 표시했습니다.
귀하의 모든 답변은 저를 가장 유망 해 보이는 트랙으로 이끌었습니다. 그의 블로그 게시물에서 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에는 주어진 유형을 다시 경로로 확인하는 단계가 포함됩니다.