zoukankan      html  css  js  c++  java
  • Windows PowerShell 2.0语言对象与对象类型

    PowerShell中遵循的一切都是对象,具有一些专属的特性,可以使用这些属性来区别它们。由于Windows和Unix/Linux之间有本质区别,因此在Windows中要实现强大的Shell外壳不能遵循Unix/Linux的技术路线。而用对象来操作Windows无疑是最好的选择,对象可以有不同的类型和原型,并且可以存储不同的数据。对象的首要的属性是其类型,类型包含对象支持的操作。对于.NET类,可以使用所有.NET对象支持的Type()方法来获取对象的类型,如下例所示:

    PS C:\> (42).GetType()

    IsPublic IsSerial Name                                     BaseType

    -------- -------- ----                                     --------

    True     True     Int32                                    System.ValueType

    PS C:\> "Hello World!".GetType()

    IsPublic IsSerial Name                                     BaseType

    -------- -------- ----                                     --------

    True     True     String                                   System.Object

    PS C:\> (1,2,3).GetType()

    IsPublic IsSerial Name                                     BaseType

    -------- -------- ----                                     --------

    True     True     Object[]                                 System.Array

    访问对象属性

    一个对象类型包含对象成员,成员具有常用属性和方法,可以是输入域或事件。属性通常用来向外界展示对象的数据,数据通常存放在一个属性中,而这个属性又以一个对象的形式存在。可以使用如下符号来访问属性值:

    PS C:\> $User=@{}

    PS C:\> $User.Name="小胖"

    PS C:\> $User.Name

    小胖

    上例创建一个新的字典对象并将其存储在$User变量中,然后将“小胖”这个字符串赋值给Name属性,最后一行取出属性值。

    属性可以是只读或者可读写的,这取决于其值是否可以修改。如果为一个只读属性执行赋值操作,Shell外壳将会报错:

    PS C:\> "Hello".length=7

    "Length" is a ReadOnly property.

    At line:1 char:9

    + "Hello". <<<< length=7

    String对象是不可变对象,其属性length是字符串对象本身固有的属性,不能通过为其赋值来改变。

    许多对象包含称为“索引值”的特殊属性,这种属性公开对象序列并允许通过一个名称或索引来访问,即通常使用的数组。例如:

    PS C:\> $friuit="apples","banana","orange"

    PS C:\> $friuit[0]

    apples

    PS C:\> $friuit[2]

    Orange

    数组下标从0开始编号,最大值为数组长度值-1。

    使用对象方法

    对象方法是描述对象支持操作的脚本块,通常携带参数并返回其他对象。如下例查找一个字符串中是否包含另外一个字符串:

    PS C:\> "Hello".Contains("Hell")

    True

    方法也可不带参数,下例用ToUpper方法将字符串对象转换为大写:

    <CENTER><ccid_nobr>

    <table width="400" border="1" cellspacing="0" cellpadding="2"

    bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center">

    <tr>

        <td bgcolor="e6e6e6" class="code" style="font-size:9pt">

        <pre><ccid_code>

    PS C:\> "lowercase Changecase Uppercase".ToUpper()

    LOWERCASE CHANGECASE UPPERCASE

    需要强调的是,不传递参数调用方法时不能省略后面的圆括号;否则PowerShell会认为是获得方法本身的对象,如下例所示:

    PS C:\> "lowercase Changecase Uppercase".ToUpper

    MemberType          : Method

    OverloadDefinitions : {System.String ToUpper(), System.String ToUpper(CultureIn

                          fo culture)}

    TypeNameOfValue     : System.Management.Automation.PSMethod

    Value               : System.String ToUpper(), System.String ToUpper(CultureInf

                          o culture)

    Name                : ToUpper

    IsInstance          : True

    上例获取方法本身的详细信息,通常情况下仅仅是想去调用该方法。

    对象适配器

    PowerShell允许使用多种应用程序的自动化对象、活动目录数据Active Directory Data、WMI,以及使用不同技术和原型实现的对象。这样需要一种机制来使得这些对象具有.NET对象那样的外观和工作方式,这种机制称为“对象适配”。对于内置对象,Shell知道如何与各种对象类型配合工作,这些数据会在一系列的适配器对象间传递;对于外部对象,Shell将其包裹在内部的.NET对象中作为的原始对象的视图出现。这种视图对象是PSObject,用适配器获取属性和方法。通常情况下PSObject仅仅作为一个原始对象,可以使用特殊的PSBase属性来获取一个原始对象,这样Shell可以使用一系列适配器操作对象。

    (1)ManagementObjectAdapter

    这个适配器针对WMI设计,使得操作WMI对象非常容易,如以对象属性的方式来遍历其属性集合:

    PS C:\> (Get-WmiObject win32_process)[0].PSBase

    .Properties["Caption"].Value

    System Idle Process

    上例使用PSBase属性获取原始的未经适配器处理的对象,通过适配器只需要如下简单代码:

    PS C:\> (Get-WmiObject win32_process)[0].Caption

    System Idle Process

    (2)DirectoryEntryAdapter

    这个适配器和Windows活动目录配合工作,工作方式与ManagementObjectAdapter相似。

    (3)DataRowAdapter

    这个适配器是关于ADO.NET DAataRow对象,可获取其行数据。例如Xml文件的内容如下:

    <Users>

                <User>

                      <Name>John</Name>

                      <Age>25</Age>

                </User>

                <User>

                      <Name>Mike</Name>

                      <Age>20</Age>

                </User>

    </Users>

    则获取其中行数据的方法如下:

    PS C:\> $ds=New-Object Data.DataSet

    PS C:\> $ds.ReadXml("C:\PowerShell\data.xml")

    InferSchema

    PS C:\> $ds.Tables[0].Rows[0].Name

    John

    PS C:\> $ds.Tables[0].Rows[0].PSBase["Name"]

    John

    (4)DataRowViewAdapter

    该适配器的工作方式与DataRowAdapter相似,它针对ADO.NET的DataRowView对象。

    (5)XmlNodeAdapter

    这是个非常重要的类型转换适配器,使对象和XML属性作为更容易操作的对象属性。.NET中XML的处理看起来太过复杂,使得用户不清楚一个值是作为XML的属性,还是作为一个元素值存在。而这个适配器将所有的值作为PowerShell代码的属性保存,下例读取XMI文件中的内容:

    PS C:\> $xmlDoc= New-Object xml.XmlDocument

    PS C:\> $xmlDoc.Load("c:\PowerShell\Data.xml")

    PS C:\> $xmlDoc.Users.User[0]

    Name                                    Age

    ----                                    ---

    John                                    25

    将内部元素以属性形式公开给外部并允许快速查询XML树,不需要通过XPath之类的重量级工具。

    (6)ComAdapter

    以往使用COM对象时必须处理编译类型信息并访问COM类库,而在PowerShell中的COM适配器可以实现这些功能并隐藏具体的细节。下例说明Internet Explorer COM对象在PowerShell中如何工作。

    首先检查当前是否运行Internet Explorer浏览器进程:

    PS C:\> Get-Process i*

    Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName

    -------  ------    -----      ----- -----   ------     -- -----------

          0       0        0         16     0               0    Idle

    可以看到未启动相关实例名为“iexplorer.exe”的进程,启动一个进程:

    PS C:\> $ie=New-Object -Com InternetExplorer.Application

    PS C:\> Get-Process i*

    Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName

    -------  ------    -----      ----- -----   ------     -- -----------

          0       0        0         16     0               0 Idle

        265      11     9048      13308    85     0.36   1876 iexplore

    PS C:\> $ie.Visible=$true

    PS C:\> $ie.Visible=$false

    PS C:\> Get-Process i*

    Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName

    -------  ------    -----      ----- -----   ------     -- -----------

          0       0        0         16     0               0    Idle

        596      23    37636      45576   161     4.09   1876  iexplore

    PS C:\> $ie.Visible=$true

    PS C:\> $ie.Visible=$false

    PS C:\> $ie.Application

    Application          : System.__ComObject

    Parent               : System.__ComObject

    Container            :

    Document             : System.__ComObject

    TopLevelContainer    : True

    Type                 : HTML 文档

    Left                 : 774

    Top                  : 500

    Width                : 692

    Height               : 457

    LocationName         : 网易

    LocationURL          : http://www.163.com/

    Busy                 : False

    Name                 : Windows Internet Explorer

    HWND                 : 591414

    FullName             : C:\Program Files\Internet Explorer\IEXPLORE.EXE

    Path                 : C:\Program Files\Internet Explorer\

    Visible              : False

    StatusBar            : True

    StatusText           : 完成

    ToolBar              : 1

    MenuBar              : True

    FullScreen           : False

    ReadyState           : 4

    Offline              : False

    Silent               : False

    RegisterAsBrowser    : False

    RegisterAsDropTarget : True

    TheaterMode          : False

    AddressBar           : True

    Resizable            : True

    注意在执行第1个语句时创建了IE进程,启动IE的同时会获得焦点,此时命令行已经失去焦点。在建立对象$ie时启动了一个IE的进程,只是这个进程在后台运行。语句$ie.Visible=$true显示界面,为了判断隐藏这个进程界面后再次显示的窗口是不是第1次启动时的窗口,使用这个IE浏览一个网站。加载网站之后,使用命令$ie.Visible=$false隐藏界面。查询进程可以看到进程仍然运行,用$ie.Application查看当前IE加载的文档信息。如果再次显示界面并关闭这个进程,再次使用$ie.Visible=$true操作对象,即可看到如下错误。这意味着在使用PowerShell的ComAdapter对COM对象进行操作时COM对象以RPC服务器的形式存在。而ComAdapter是服务的客户端,它向RPC服务器发出请求。服务器执行相应的操作并返回结果,整个过程对应针对COM对象应用的操作:

    PS C:\> $ie.Visible=$true

    Exception setting "Visible": "RPC 服务器不可用。 (异常来自 HRESULT:0x800706BA)"

    At line:1 char:5

    + $ie. <<<< Visible=$true

    类型扩展

    对象适配器是改变对象表现方式的主要机制,但是其根源仍然是PowerShell。适配器作为.NET对象来执行,而且是PowerShell代码基础不可分割的组成部分。由于没有提供接口允许用户创建自己的适配器或在现有适配器之上扩展,因此PowerShell提供了一种机制用于修改对象类型。即对象扩展,使用户能够通过提供额外的代码和数据在运行时为对象和对象类型添加成员,包括属性和方法。如下代码获取System.Diagnostics.Process类型的扩展属性:

    PS C:\> (Get-Process)[0] |Get-Member -type Aliasproperty

       TypeName: System.Diagnostics.Process

    Name    MemberType    Definition

    ----    ----------    ----------

    Handles AliasProperty Handles = Handlecount

    Name    AliasProperty Name = ProcessName

    NPM     AliasProperty NPM = NonpagedSystemMemorySize

    PM      AliasProperty PM = PagedMemorySize

    VM      AliasProperty VM = VirtualMemorySize

    WS      AliasProperty WS = WorkingSet

    这段代码获取所有进程中最高优先级的进程,并显示其别名属性。可以看到PowerShell扩展了Process类型,所以能够使用其中一些属性公开的较短名称,用Name来代替ProcessName;用WS来代替WorkingSet等。

    别名属性仅仅是通过名称引用其他属性并返回该属性的值,属性别名化通常是用来缩短一些最常用的特性来使得对象用起来方便,如:

    PS C:\> Get-Member -Input(1,2,3) -type AliasProperty

       TypeName: System.Object[]

    Name  MemberType    Definition

    ----  ----------    ----------

    Count AliasProperty Count = Length

    能够通过访问PSExtended属性来访问类型对象视图,下例获取Process类型的所有扩展成员:

    <CENTER><ccid_nobr>

    <table width="400" border="1" cellspacing="0" cellpadding="2"

    bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center">

    <tr>

        <td bgcolor="e6e6e6" class="code" style="font-size:9pt">

        <pre><ccid_code>

    PS C:\> (Get-Process)[0].PSExtended | Get-Member

       TypeName: System.Management.Automation.PSMemberSet

    Name            MemberType     Definition

    ----            ----------     ----------

    Handles         AliasProperty  Handles = Handlecount

    Name            AliasProperty  Name = ProcessName

    NPM             AliasProperty  NPM = NonpagedSystemMemorySize

    PM              AliasProperty  PM = PagedMemorySize

    VM              AliasProperty  VM = VirtualMemorySize

    WS              AliasProperty  WS = WorkingSet

    __NounName      NoteProperty   System.String __NounName=Process

    PSConfiguration PropertySet    PSConfiguration {Name, Id, PriorityClass, Fil...

    PSResources     PropertySet    PSResources {Name, Id, Handlecount, WorkingSe...

    Company         ScriptProperty System.Object Company {get=$this.Mainmodule.F...

    CPU             ScriptProperty System.Object CPU {get=$this.TotalProcessorTi...

    Description     ScriptProperty System.Object Description {get=$this.Mainmodu...

    FileVersion     ScriptProperty System.Object FileVersion {get=$this.Mainmodu...

    Path            ScriptProperty System.Object Path {get=$this.Mainmodule.File...

    Product         ScriptProperty System.Object Product {get=$this.Mainmodule.F...

    ProductVersion  ScriptProperty System.Object ProductVersion {get=$this.Mainm...

    总结

    PowerShell作为强大且复杂的语言,并没有过于严格或对新手不友好。因为它把所有的对象类型通过适配器和扩展统一存取,所以用户能够找到快速入手的途径。本文分别针对PowerShell的对象属性,对象方法和对象适配器,以及对象类型扩展进行描述,最常用的对象是获取实体扩展,从而提高了脚本编写者的创造性,并降低了学习的难度。

    微软MSDN原文地址:http://msdn.microsoft.com/zh-cn/ff943778.aspx

    赛迪网原文地址:http://news.ccidnet.com/art/32857/20100608/2081057_1.html

    作者: 付海军
    出处:http://fuhj02.cnblogs.com
    版权:本文版权归作者和博客园共有
    转载:欢迎转载,为了保存作者的创作热情,请按要求【转载】,谢谢
    要求:未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任
    个人网站: http://txj.shell.tor.hu

  • 相关阅读:
    CSS 中 Font-Family 中英文对照表
    0号首页,移动应用快捷门户
    身边的大数据和我们的着手点
    php单例模式
    原生JS实现ajax与ajax的跨域请求
    two.js之实现动画效果
    H5中的拖放
    简说chart2.4的应用,以及Uncaught ReferenceError : require is not defined的解决
    JS中的作用域以及全局变量的问题
    JavaScript 框架------------AngularJS(下)
  • 原文地址:https://www.cnblogs.com/fuhj02/p/1877328.html
Copyright © 2011-2022 走看看