当我在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;
。
答案 0 :(得分:55)
这样的命名空间级别真的没什么。我经常将常用类型分配给变量,然后实例化它们:
$thingtype = [FooCompany.Bar.Qux.Assembly.With.Ridiculous.Long.Namespace.I.Really.Mean.It.Thingamabob];
$blurb = New-Object $thingtype.FullName
如果不重复使用该类型,可能不值得,但我相信这是你能做到的最好的。
答案 1 :(得分:34)
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
是语法错误。 )
答案 2 :(得分: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
答案 3 :(得分: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
答案 4 :(得分: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)
}
}
}
}
答案 5 :(得分:5)
如果您只需要创建类型的实例,则可以将长命名空间的名称存储在字符串中:
$st = "System.Text"
$sb = New-Object "$st.StringBuilder"
它没有C#中的using
指令那么强大,但至少它很容易使用。
答案 6 :(得分:2)
感谢大家的投入。我已将Richard Berg的贡献标记为答案,因为它与我正在寻找的内容非常相似。
你的所有答案都让我走上了最有希望的轨道:在his blog post中,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()
这将产生一个很好的通用List of Thingamabob。当然,我只是将路径定义包含在另一个实用功能中。扩展的get-type将包括在路径中再次解析任何给定类型的步骤。
答案 7 :(得分:0)
#Requires -Version 5
using namespace System.Management.Automation.Host
#using module
答案 8 :(得分:-2)
我意识到这是一篇很老的帖子,但我一直在寻找相同的东西并遇到过这个问题:http://weblogs.asp.net/adweigert/powershell-adding-the-using-statement
编辑:我想我应该指定它允许你使用熟悉的语法......
using ($x = $y) { ... }