当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 创建 .NET 和 COM 对象

作者:精品下载站 日期:2024-12-14 03:03:19 浏览:10 分类:玩电脑

创建 .NET 和 COM 对象


该示例仅在 Windows 平台上运行。

有些软件组件具有 .NET Framework 和 COM 接口,使您能够执行许多系统管理任务。 PowerShell 允许您使用这些组件,因此您不限于可以使用 cmdlet 执行的任务。 PowerShell 初始版本中的许多 cmdlet 不适用于远程计算机。我们将演示如何通过直接从 PowerShell 使用 .NET Framework System.Diagnostics.EventLog 类来管理事件日志时绕过此限制。

使用 New-Object 进行事件日志访问

.NET Framework 类库包含一个名为System.Diagnostics.EventLog 的类,可用于管理事件日志。您可以使用带有 TypeName 参数的 New-Object cmdlet 创建 .NET Framework 类的新实例。例如,以下命令创建事件日志引用:

New-Object -TypeName System.Diagnostics.EventLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----

尽管该命令创建了 EventLog 类的实例,但该实例不包含任何数据。那是因为我们没有指定特定的事件日志。如何获得真实的事件日志?

将构造函数与 New-Object 一起使用

要引用特定事件日志,您需要指定日志名称。 New-Object 有一个 ArgumentList 参数。作为值传递给此参数的参数由对象的特殊启动方法使用。该方法称为构造函数,因为它用于构造对象。例如,要获取对应用程序日志的引用,您可以指定字符串“Application”作为参数:

New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application
Max(K) Retain OverflowAction        Entries Name
------ ------ --------------        ------- ----
16,384      7 OverwriteOlder          2,160 Application

笔记

由于大多数 .NET 类都包含在 System 命名空间中,因此,如果 PowerShell 无法找到与您指定的类型名称。这意味着您可以指定 Diagnostics.EventLog 而不是 System.Diagnostics.EventLog

在变量中存储对象

您可能想要存储对对象的引用,以便可以在当前 shell 中使用它。尽管 PowerShell 允许您使用管道完成大量工作,从而减少了对变量的需求,但有时在变量中存储对对象的引用可以更方便地操作这些对象。

任何有效的 PowerShell 命令的输出都可以存储在变量中。变量名称始终以 $ 开头。如果要将应用程序日志引用存储在名为 $AppLog 的变量中,请键入变量名称,后跟等号,然后键入用于创建应用程序日志对象的命令:

$AppLog = New-Object -TypeName System.Diagnostics.EventLog -ArgumentList Application

如果您随后输入 $AppLog,您可以看到它包含应用程序日志:

$AppLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
  16,384      7 OverwriteOlder          2,160 Application

使用 New-Object 访问远程事件日志

上一节中使用的命令是针对本地计算机的; Get-EventLog cmdlet 可以做到这一点。要访问远程计算机上的应用程序日志,您必须提供日志名称和计算机名称(或 IP 地址)作为参数。

$RemoteAppLog = New-Object -TypeName System.Diagnostics.EventLog Application, 192.168.1.81
$RemoteAppLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
     512      7 OverwriteOlder            262 Application

现在我们已经引用了存储在 $RemoteAppLog 变量中的事件日志,我们可以对其执行哪些任务?

使用对象方法清除事件日志

对象通常具有可以调用来执行任务的方法。您可以使用 Get-Member 显示与对象关联的方法。以下命令和选定的输出显示了 EventLog 类的一些方法:

$RemoteAppLog | Get-Member -MemberType Method
   TypeName: System.Diagnostics.EventLog

Name                      MemberType Definition
----                      ---------- ----------
...
Clear                     Method     System.Void Clear()
Close                     Method     System.Void Close()
...
GetType                   Method     System.Type GetType()
...
ModifyOverflowPolicy      Method     System.Void ModifyOverflowPolicy(Overfl...
RegisterDisplayName       Method     System.Void RegisterDisplayName(String ...
...
ToString                  Method     System.String ToString()
WriteEntry                Method     System.Void WriteEntry(String message),...
WriteEvent                Method     System.Void WriteEvent(EventInstance in...

Clear() 方法可用于清除事件日志。调用方法时,即使该方法不需要参数,也必须始终在方法名称后面加上括号。这使得 PowerShell 能够区分该方法和具有相同名称的潜在属性。键入以下内容来调用 Clear 方法:

$RemoteAppLog.Clear()
$RemoteAppLog
  Max(K) Retain OverflowAction        Entries Name
  ------ ------ --------------        ------- ----
     512      7 OverwriteOlder              0 Application

请注意,事件日志已被清除,现在有 0 个条目,而不是 262 个。

使用 New-Object 创建 COM 对象

您可以使用 New-Object 来处理组件对象模型 (COM) 组件。组件范围从 Windows 脚本宿主 (WSH) 附带的各种库到大多数系统上安装的 ActiveX 应用程序(例如 Internet Explorer)。

New-Object 使用 .NET Framework 运行时可调用包装器来创建 COM 对象,因此它与 .NET Framework 在调用 COM 对象时具有相同的限制。要创建 COM 对象,您需要使用要使用的 COM 类的编程标识符或 ProgId 来指定 ComObject 参数。对 COM 使用限制以及确定系统上可用的 ProgId 的完整讨论超出了本用户指南的范围,但来自 WSH 等环境的大多数众所周知的对象都可以在 PowerShell 中使用。

您可以通过指定以下 progid 创建 WSH 对象:WScript.ShellWScript.NetworkScripting.DictionaryScripting。文件系统对象。以下命令创建这些对象:

New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject

尽管这些类的大部分功能可以在 Windows PowerShell 中以其他方式使用,但使用 WSH 类仍然可以更轻松地完成一些任务(例如创建快捷方式)。

使用 WScript.Shell 创建桌面快捷方式

使用 COM 对象可以快速执行的一项任务是创建快捷方式。假设您要在桌面上创建一个链接到 PowerShell 主文件夹的快捷方式。您首先需要创建对 WScript.Shell 的引用,我们将其存储在名为 $WshShell 的变量中:

$WshShell = New-Object -ComObject WScript.Shell

Get-Member 适用于 COM 对象,因此您可以通过键入以下内容来探索对象的成员:

$WshShell | Get-Member
   TypeName: System.__ComObject#{41904400-be18-11d3-a28b-00104bd35090}

Name                     MemberType            Definition
----                     ----------            ----------
AppActivate              Method                bool AppActivate (Variant, Va...
CreateShortcut           Method                IDispatch CreateShortcut (str...
...

Get-Member 有一个可选的 InputObject 参数,您可以使用它代替管道来向 Get-Member 提供输入。如果您改为使用命令 Get-Member -InputObject $WshShell,您将获得与上面所示相同的输出。如果您使用InputObject,它会将其参数视为单个项目。这意味着,如果变量中有多个对象,Get-Member 会将它们视为对象数组。例如:

$a = 1,2,"three"
Get-Member -InputObject $a
TypeName: System.Object[]
Name               MemberType    Definition
----               ----------    ----------
Count              AliasProperty Count = Length
...

WScript.Shell CreateShortcut 方法接受一个参数,即要创建的快捷方式文件的路径。我们可以输入桌面的完整路径,但还有一种更简单的方法。桌面通常由当前用户的主文件夹中名为 Desktop 的文件夹表示。 Windows PowerShell 有一个变量 $HOME,其中包含此文件夹的路径。我们可以使用此变量指定主文件夹的路径,然后通过键入以下内容添加桌面文件夹的名称和要创建的快捷方式的名称:

$lnk = $WshShell.CreateShortcut("$HOME\Desktop\PSHome.lnk")

当您使用看起来像双引号内的变量名称的内容时,PowerShell 会尝试替换匹配的值。如果您使用单引号,PowerShell 不会尝试替换变量值。例如,尝试键入以下命令:

"$HOME\Desktop\PSHome.lnk"
C:\Documents and Settings\aka\Desktop\PSHome.lnk
'$HOME\Desktop\PSHome.lnk'
$HOME\Desktop\PSHome.lnk

我们现在有一个名为 $lnk 的变量,其中包含新的快捷方式引用。如果您想查看其成员,可以通过管道将其传递给 Get-Member。下面的输出显示了我们需要用来完成创建快捷方式的成员:

$lnk | Get-Member
TypeName: System.__ComObject#{f935dc23-1cf0-11d0-adb9-00c04fd58a0b}
Name             MemberType   Definition
----             ----------   ----------
...
Save             Method       void Save ()
...
TargetPath       Property     string TargetPath () {get} {set}

我们需要指定 TargetPath,即 PowerShell 的应用程序文件夹,然后通过调用 Save 方法保存快捷方式。 PowerShell 应用程序文件夹路径存储在变量 $PSHome 中,因此我们可以通过键入以下内容来执行此操作:

$lnk.TargetPath = $PSHome
$lnk.Save()

从 PowerShell 使用 Internet Explorer

许多应用程序(包括 Microsoft Office 应用程序系列和 Internet Explorer)都可以通过使用 COM 实现自动化。以下示例说明了使用基于 COM 的应用程序时涉及的一些典型技术和问题。

您可以通过指定 Internet Explorer ProgId InternetExplorer.Application 创建 Internet Explorer 实例:

$ie = New-Object -ComObject InternetExplorer.Application

此命令启动 Internet Explorer,但不使其可见。如果您输入 Get-Process,您可以看到名为 iexplore 的进程正在运行。事实上,如果退出 PowerShell,该进程将继续运行。您必须重新启动计算机或使用任务管理器等工具来结束 iexplore 进程。

笔记

作为单独进程启动的 COM 对象(通常称为 ActiveX 可执行文件)在启动时可能会或可能不会显示用户界面窗口。如果他们创建一个窗口但不使其可见(例如 Internet Explorer),则焦点通常会移动到 Windows 桌面。您必须使窗口可见才能与其交互。

通过输入 $ie | Get-Member,您可以查看 Internet Explorer 的属性和方法。要查看 Internet Explorer 窗口,请通过键入以下内容将 Visible 属性设置为 $true

$ie.Visible = $true

然后,您可以使用 Navigate 方法导航到特定网址:

$ie.Navigate("https://devblogs.microsoft.com/scripting/")

使用 Internet Explorer 对象模型的其他成员,可以从网页检索文本内容。以下命令显示当前网页正文中的 HTML 文本:

$ie.Document.Body.InnerText

要从 PowerShell 中关闭 Internet Explorer,请调用其 Quit() 方法:

$ie.Quit()

$ie 变量不再包含有效引用,尽管它仍然显示为 COM 对象。如果您尝试使用它,PowerShell 将返回一个自动化错误:

$ie | Get-Member
Get-Member : Exception retrieving the string representation for property "Appli
cation" : "The object invoked has disconnected from its clients. (Exception fro
m HRESULT: 0x80010108 (RPC_E_DISCONNECTED))"
At line:1 char:16
+ $ie | Get-Member <<<<

您可以使用 $ie=$null 之类的命令删除剩余的引用,也可以通过键入以下内容完全删除变量:

Remove-Variable ie

笔记

当您删除对 ActiveX 可执行文件的引用时,对于 ActiveX 可执行文件是退出还是继续运行,没有通用标准。根据具体情况,例如应用程序是否可见、编辑的文档是否正在其中运行,甚至 PowerShell 是否仍在运行,应用程序可能会退出,也可能不会退出。因此,您应该测试要在 PowerShell 中使用的每个 ActiveX 可执行文件的终止行为。

获取有关 .NET Framework 包装的 COM 对象的警告

在某些情况下,COM 对象可能具有由 New-Object 使用的关联 .NET Framework 运行时可调用包装器 (RCW)。由于 RCW 的行为可能与普通 COM 对象的行为不同,因此 New-Object 有一个 Strict 参数来警告您有关 RCW 访问的信息。如果指定 Strict 参数,然后创建使用 RCW 的 COM 对象,您会收到一条警告消息:

$xl = New-Object -ComObject Excel.Application -Strict
New-Object : The object written to the pipeline is an instance of the type "Mic
rosoft.Office.Interop.Excel.ApplicationClass" from the component's primary interop assembly. If
this type exposes different members than the IDispatch members , scripts written to work with this
object might not work if the primary interop assembly isn't installed. At line:1 char:17 + $xl =
New-Object <<<< -ComObject Excel.Application -Strict

尽管仍会创建该对象,但系统会警告您它不是标准 COM 对象。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯