about_Methods
简短说明
介绍如何使用方法对 PowerShell 中的对象执行操作。
长说明
PowerShell 使用对象来表示数据存储中的项或计算机的状态。 例如,FileInfo 对象表示文件系统驱动器中的文件,ProcessInfo 对象表示计算机上的进程。
对象具有属性(用于存储有关对象的数据)和方法(用于更改对象)。
“方法”是一组指令,用于指定可以对对象执行的操作。 例如,FileInfo
对象包括 CopyTo
方法,用于复制 FileInfo
对象所表示的文件。
若要获取任意对象的方法,请使用 Get-Member
cmdlet。 使用其 MemberType 属性,该属性的值为“Method”。 以下命令获取进程对象的方法。
Get-Process | Get-Member -MemberType Method
TypeName: System.Diagnostics.Process
Name MemberType Definition
---- ---------- ----------
BeginErrorReadLine Method System.Void BeginErrorReadLine()
BeginOutputReadLine Method System.Void BeginOutputReadLine()
...
Kill Method System.Void Kill()
Refresh Method System.Void Refresh()
Start Method bool Start()
ToString Method string ToString()
WaitForExit Method bool WaitForExit(int milliseconds), ...
WaitForInputIdle Method bool WaitForInputIdle(int millisecon...
若要执行或“调用”对象的方法,请键入一个点 (.)、方法名称和一组括号“()”。 如果方法具有参数,请将参数值置于括号内。 每个方法调用都需要括号,即使没有参数。 如果该方法采用多个参数,则应使用逗号将它们分隔开来。
例如,以下命令调用进程的 Kill 方法来结束计算机上的记事本进程。
$notepad = Get-Process notepad
$notepad.Kill()
可以通过组合上述语句来缩短此示例。
(Get-Process Notepad).Kill()
Get-Process
命令以括号括起,以确保它在调用 Kill 方法之前运行。 然后在返回的 Process
对象上调用 Kill
方法。
另一个非常有用的方法是字符串的 Replace
方法。 Replace
方法将替换字符串中的文本。 在下面的示例中,点 (.) 可以紧跟在字符串的右引号之后。
'this is rocket science'.Replace('rocket', 'rock')
this is rock science
如前面的示例所示,在你获取的对象上,你可以使用命令、变量中的对象或生成对象的任何内容(如引号中的字符串)来调用方法。
从 PowerShell 4.0 开始,支持通过使用动态方法名称来调用方法。
了解方法
若要查找对象方法的定义,请转到对象类型的帮助主题并查找其方法页。 例如,以下页面介绍 System.Diagnostics.Process 进程对象的方法。
若要确定方法的参数,请查看方法定义,这类似于 PowerShell cmdlet 的语法关系图。
方法定义可能具有一个或多个方法签名,类似于 PowerShell cmdlet 的参数集。 签名显示调用该方法的所有有效命令格式。
例如,FileInfo
类的 CopyTo
方法包含以下两个方法签名:
CopyTo(String destFileName)
CopyTo(String destFileName, Boolean overwrite)
第一个方法签名采用目标文件名(和路径)。 以下示例使用第一个 CopyTo
方法将 Final.txt
文件复制到 C:\Bin
目录。
(Get-ChildItem c:\final.txt).CopyTo("c:\bin\final.txt")
注意
与 PowerShell 的自变量模式不同,对象方法在表达式模式下执行,这是针对 PowerShell 所基于的 .NET 框架的传递。 在表达式模式下,不允许裸字自变量(不带引号的字符串)。 将路径用作参数时,可以看到此差异,而不是路径作为参数。 可以在 about_Parsing 中详细了解分析模式
第二个方法签名采用目标文件名和布尔值,该布尔值确定是否应覆盖目标文件(如果已存在)。
以下示例使用第二个 CopyTo
方法将 Final.txt
文件复制到 C:\Bin
目录,覆盖现有文件。
(Get-ChildItem c:\final.txt).CopyTo("c:\bin\final.txt", $true)
成员访问枚举
从 PowerShell 3.0 开始,当你使用成员访问运算符 (.
) 访问列表集合中不存在的方法时,PowerShell 会自动枚举集合中的项并调用每个项上的方法。 有关详细信息,请参阅 about_Member-Access_Enumeration。
示例
以下示例运行对象集合中各个进程对象的 Kill 方法。
第一个命令启动记事本进程的三个实例。 Get-Process
获取记事本进程的所有三个实例,并将其保存在 $p
变量中。
Notepad; Notepad; Notepad
$p = Get-Process Notepad
$p.Count
3
下一个命令对 $p
变量中的所有三个进程运行 Kill 方法。 即使进程集合没有 Kill
方法,此命令也有效。
$p.Kill()
Get-Process Notepad
Get-Process
命令确认 Kill
方法有效。
Get-Process : Cannot find a process with the name "notepad". Verify the proc
ess name and call the cmdlet again.
At line:1 char:12
+ Get-Process <<<< notepad
+ CategoryInfo : ObjectNotFound: (notepad:String) [Get-Process]
, ProcessCommandException
+ FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShel
l.Commands.GetProcessCommand
此示例在功能上等效于使用 Foreach-Object
cmdlet 在集合中的每个对象上运行该方法。
$p | ForEach-Object {$_.Kill()}
ForEach 和 Where 方法
从 PowerShell 4.0 开始,支持使用方法语法的集合筛选。 因此,可以在处理集合 ForEach
和 Where
时使用两个新方法。
可阅读 about_arrays 了解有关这些方法的详细信息
当存在多个重载时调用特定方法
调用 .NET 方法时,请考虑以下方案。 如果方法采用对象,但其通过接口进行的重载采用更具体的类型,则 PowerShell 会选择那个接受该对象的方法,除非你显式将其强制转换为该接口。
Add-Type -TypeDefinition @'
// Interface
public interface IFoo {
string Bar(int p);
}
// Type that implements the interface
public class Foo : IFoo {
// Direct member method named 'Bar'
public string Bar(object p) { return $"object: {p}"; }
// *Explicit* implementation of IFoo's 'Bar' method().
string IFoo.Bar(int p) {
return $"int: {p}";
}
}
'@
在此示例中,选择了 Bar 方法的不太具体的 object
重载。
[Foo]::new().Bar(1)
object: 1
在此示例中,我们将该方法强制转换为接口 IFoo,以选择 Bar 方法的更具体的重载。
([IFoo] [Foo]::new()).Bar(1)
int: 1
使用采用文件系统路径的 .NET 方法
PowerShell 支持每个进程有多个运行空间。 每个运行空间都有自己的当前目录。 这不同于当前进程的工作目录:[System.Environment]::CurrentDirectory
。
.NET 方法使用进程工作目录。 PowerShell cmdlet 使用运行空间位置。 此外,.NET 方法仅适用于本机文件系统路径,而不适用于 PowerShell 路径对象。 若要将 PowerShell 路径与 .NET 方法配合使用,必须先将路径解析为文件系统本机路径,然后再将其传递给 .NET 方法。