Эквивалентно С# "используя" ключевое слово в powershell?
Когда я использую другой объект в .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
Отправляйте это сообщение в блоге пару лет назад: 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
Ответ 2
На уровне пространства имен действительно ничего нет. Я часто назначаю обычно используемые типы для переменных, а затем создаю их экземпляр:
$thingtype = [FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It.Thingamabob];
$blurb = New-Object $thingtype.FullName
Возможно, это не стоит, если тип не будет использоваться повторно, но я считаю, что это лучшее, что вы можете сделать.
Ответ 3
PowerShell 5.0 (входит в WMF5 или Windows 10 и выше) добавляет конструкцию using namespace
к языку. Вы можете использовать его в своем script следующим образом:
#Require -Version 5.0
using namespace FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It
$blurb = [Thingamabob]::new()
(Оператор #Require
в первой строке не нужен для использования using namespace
, но это предотвратит запуск script в PS 4.0 и ниже, где using namespace
является синтаксической ошибкой.)
Ответ 4
Это просто шутка, шутка...
$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
Ответ 5
Здесь приведен код, который работает в 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)
}
}
}
}
Ответ 6
Если вам просто нужно создать экземпляр вашего типа, вы можете сохранить имя длинного пространства имен в строке:
$st = "System.Text"
$sb = New-Object "$st.StringBuilder"
Это не так сильно, как директива using
в С#, но, по крайней мере, очень проста в использовании.
Ответ 7
Спасибо всем за ваш вклад. Я отметил вклад Ричарда Берга в качестве ответа, потому что он наиболее близко напоминает то, что я ищу.
Все ваши ответы привели меня на трек, который кажется наиболее перспективным: В его сообщение в блоге 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 будет включать в себя шаг для разрешения любого заданного типа снова путь.
Ответ 8
#Requires -Version 5
using namespace System.Management.Automation.Host
#using module
Ответ 9
Я понимаю, что это старый пост, но я искал то же самое и наткнулся на это: http://weblogs.asp.net/adweigert/powershell-adding-the-using-statement
Изменить: я полагаю, я должен указать, что он позволяет использовать знакомый синтаксис...
using ($x = $y) { ... }