PowerShell2.0之与COM对象交互(五)与脚本宿主代码协同工作
网络中存在大量由VBScript和Jscript或者其他Windows脚本宿主相关的语言编写的代码,其中相当一部分用对应语言实现很简短,而且有部分代码甚至不能转换为PowerShell代码。丢弃所有这些代码并且完全使用PowerShell重写很不明智,因此需要在PowerShell中有一种重用Jscript和VBScript脚本的代码方法。
MSScriptControl这个COM对象可以作为脚本环境的宿主,其ProgID是MSScriptControl.ScriptControl。用户可以用其注册并执行代码,使用这个对象作为从PowerShell中调用现有VBScript和Jscript脚本的方法。一旦导入脚本,即可调用其中的函数,传递参数并返回值。
为了示范脚本如何控制对象的操作,下面演示计算文件大小的两个实例,分别是Jscript编写的FileSize.js和VBScirpt编写的FileSize.vbs。两个脚本中包括定义为“GetFileSize()”的函数接受一个文件路径为参数,并返回文件路径及其大小。Jscript脚本的源代码如下:
function GetFileSize(filePath)
{
var fileSystem = new ActiveXObject("Scripting.FileSystemObject");
var file = fileSystem.GetFile(filePath);
return (filePath + " has " + file.Size + " bytes.");
}
VBScript脚本的代码如下:
Function GetFileSize(filePath)
Dim fileSystem
Set fileSystem = CreateObject("Scripting.FileSystemObject")
Dim file
Set file = fileSystem.GetFile(filePath)
GetFileSize = filePath & " has " & file.Size & " bytes."
End Function
能够看到每种语言都有其相对特殊的函数声明方法、变量,以及与COM对象操作的方法。为了能够从PowerShell中调用Jscript函数,需要读取FileSize.js文件内容并且传递给脚本空间的AddCode()方法。这个方法将会执行函数定义,并使其在后面可用。
1 执行代码
在将脚本代码包含在脚本控件中后,即可调用在Jscript中定义的函数,为此可以使用Eval()或者Run()方法。Eval()方法将字符串作为输入并执行,其返回值将会把结果返回给调用方,本实例为PowerShell;Run()方法可以接受多个参数,其中第1个是函数名,后续是将要传递给函数的参数,该方法返回函数的返回值给PowerShell的脚本。在这里创建一个名为“JScriptEval.ps1”的脚本,分别使用Eval()和Run()调用Jscript函数,代码如下:
$jscript = New-Object -COM MSScriptControl.ScriptControl
$jscript.Language = "JScript"
$jsLines = Get-Content "FileSize.js"
$jsCode = [string]::Join("`n", $jsLines)
$jscript.AddCode($jsCode)
$fileName = (dir FileSize.js).FullName
Write-Host "Using Eval"
$jscript.Eval("GetFileSize(`"$($fileName.Replace('\', '\\'))`")")
Write-Host "Using Run"
$jscript.Run("GetFileSize", $fileName)
其中将Language属性设置为“JScript”,表示其后调用的所有代码都是Jscript。接下来用Get-Content cmdlet获取FileSize.js文件中包含的所有内容,然后为各行代码添加换行符,并将其拼接后传递给AddCode()方法。
Eval()方法需要将双引号转义为Jscript字符串,把反斜杠替换为双反斜杠。因为反斜杠在Jscript中是一个有特殊含义的转义字符,需要被转义;Run()方法不需要执行任何转义操作,因为使用的是脚本控件的机制传递参数。图1所示为该脚本的执行结果。
图1 执行结果
Eval()和Run()方法的执行结果相同,使用Run()方法可避免很多不必要的麻烦。
下面创建一个名为“VBScriptEval.ps1”的脚本,通过调用VBScript代码定义的GetFileSize()函数,代码如下:
$vbscript = New-Object -COM MSScriptControl.ScriptControl
$vbscript.Language = "VBScript"
$vbsLines = Get-Content "FileSize.vbs"
$vbsCode = [string]::Join("`n", $vbsLines)
$vbscript.AddCode($vbsCode)
$fileName = (dir FileSize.vbs).FullName
Write-Host "Using Eval"
$vbscript.Eval("GetFileSize(`"$fileName`")")
Write-Host "Using Run"
$vbscript.Run("GetFileSize", $fileName)
这个脚本与前面Jscript版本的最大不同是创建脚本控件对象的Language属性值。需要强调的一点是在VBScript脚本中调用Eval()方法时,不需要转义反斜杠字符,因其在VBScript中并不包含特殊含义。该脚本的执行结果如图2所示。
图2 执行结果
2 在MSScriptControl中公开对象
Eval()和Run()方法为其他语言提供了很好的访问途径,但其表现不像真正的方法。如果能调用脚本控件对象的特性,即动态对象生成,即可很好地解决这个问题。MSScriptControl对象有一个CodeObject属性,用于将附加到脚本控件的代码返回一个匿名对象,代码对象将会公开作为公开方法添加的所有函数,这样即可使得外部脚本对象的操作与常规的.NET对象毫无差别。
下面使用该属性调用JScript函数,创建一个新的脚本文件“JScriptCodeObject.ps1”。配置一个脚本对象,通过动态生成的对象调用其函数,代码如下:
$jscript = New-Object -COM MSScriptControl.ScriptControl
$jscript.Language = "JScript"
$jsLines = Get-Content "FileSize.js"
$jsCode = [string]::Join("`n", $jsLines)
$jscript.AddCode($jsCode)
$fileName = (dir FileSize.js).FullName
$fileSize = $jscript.CodeObject
$fileSize.GetFileSize($fileName)
脚本的执行结果如图3所示。
图3 执行结果
接下对比VBScript版本,下面是脚本VBScriptCodeObject.ps1的代码:
$vbscript = New-Object -COM MSScriptControl.ScriptControl
$vbscript.Language = "VBScript"
$vbsLines = Get-Content "FileSize.vbs"
$vbsCode = [string]::Join("`n", $vbsLines)
$vbscript.AddCode($vbsCode)
$fileName = (dir FileSize.vbs).FullName
$fileSize = $vbscript.CodeObject
$fileSize.GetFileSize($fileName)
执行结果如图4所示。
图4 执行结果
3 总 结
PowerShell为COM对象提供了近乎完美的支持,本文的实例涉及主要的交互性操作,如使用集合和索引属性。只要不同的应用程序和服务已经具有公开的COM自动化接口,则可尝试使用COM来提高工作效率。本文介绍了针对Windows脚本宿主的自动化编程,用户可以通过以上的介绍扩展到对其他COM对象进行操作。
出处:http://fuhj02.cnblogs.com
版权:本文版权归作者和博客园共有
转载:欢迎转载,为了保存作者的创作热情,请按要求【转载】,谢谢
要求:未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任
个人网站: http://txj.shell.tor.hu/
转载于:https://www.cnblogs.com/fuhj02/archive/2010/12/25/1916680.html
PowerShell2.0之与COM对象交互(五)与脚本宿主代码协同工作相关推荐
- 【Groovy】Groovy 脚本调用 ( Groovy 类中调用 Groovy 脚本 | 创建 GroovyShell 对象并执行 Groovy 脚本 | 完整代码示例 )
文章目录 一.Groovy 类中调用 Groovy 脚本 1.创建 GroovyShell 对象并执行 Groovy 脚本 2.代码示例 二.完整代码示例 1.调用者 Groovy 脚本的类 2.被调 ...
- java对象交互_Java 2 对象交互
2.1 对象交互 2.1.1 时钟的设计: 用一个类来表示时钟和分钟. 对象Display: (属性)成员变量value limit (操作)成员函数increase getValue package ...
- java 给对象创建实例_Java中创建(实例化)对象的五种方式
Java中创建(实例化)对象的五种方式1.用new语句创建对象,这是最常见的创建对象的方法. 2.通过工厂方法返回对象,如:String str = String.valueOf(23); 3.运用反 ...
- 在Simscape中创建虚拟机器人环境(二):添加物理、对象交互和自主
在Simscape中创建虚拟机器人环境:添加物理.对象交互和自主 由阿列克莎·桑切斯, (2020年8月31日),转载博客地址:https://blogs.mathworks.com/racing-l ...
- Java中创建(实例化)对象的五种方式
Java中创建(实例化)对象的五种方式 1.用new语句创建对象,这是最常见的创建对象的方法. 2.通过工厂方法返回对象,如:String str = String.valueOf(23); 3.运 ...
- 从零开始入门创作游戏——对象交互与UI展示
做教程远比自己开发游戏要花时间...继续写小恐龙的游戏教程 环境搭建在这里 从零开始入门创作游戏--Unity3d的环境搭建_默哀d的博客-CSDN博客 素材导入和基本页面介绍在这里 从零开始入门创作 ...
- 创建(实例化)对象的五种方式
目录 一.Java中创建(实例化)对象的五种方式 1.new关键字创建对象; 2.调用对象的clone()方法创建对象 3.通过反射对对象进行初始化 4.序列化 5.通过工厂方法返回对象 二.Java ...
- PowerShell2.0之维护网络(三)设置网络适配器
如果计算机中有多个网络适配器,在Windows原有的cmd下配置其属性很困难,用户必须确保配置了适当的适配器并确认要禁用的不是正在使用中的网络适配器.本节介绍在处理多个网络适配器时可能出现的问题及其解 ...
- Power BI 可视化交互/视觉对象交互
xx Power BI的官方文档特别好,但是具体到自己使用的时候,有些知识点,可能看完文档忘了,导致有些功能做不出来...网络上资料还比较匮乏... 自己没事还是多总结下吧... 比如: 文档上写的很 ...
最新文章
- Ubantu下hadoop运行第一个例子wordcount过程
- windows7 下的日期没有internet时间的选项卡
- 【iCore1S 双核心板_ARM】例程十二:DMA实验——存储器到存储器的传输
- 统计建模与r软件_【统计建模与R软件笔记】008 描述统计量(1)
- Tokenview:交易所比特币净流出量大幅增加
- UVa1401 Remember the Word(DP+Trie树)
- 解决window.location.href 下载文件时,一次点击产生两次下载+页面跳转问题
- 智能家居实训系统的项目有感!
- 内存颗粒位宽和容量_内存颗粒有没有多与少的区别啊?或者说比较多的颗粒比少的颗粒好些?...
- 程序员,技术主管和架构师
- 2.3 Visio画虚线后插入word或PPT变为实线
- python风变编程和扇贝编程_想学习phython ,纠结是扇贝编程还是风变编程?
- 用devc++表白_表白墙第42期|别人深夜买醉,我只想买你的心
- Flask PyMongo的基本使用
- ubuntu设置自动关机
- 对行场、带宽很好解析的一文章
- ASM学习笔记1 - 初识ClassVistor ——以ClassReader的应用为例
- umi路由懒加载和权限验证(基于React)
- 固态硬盘原理与ASS SSD Benchmark
- 一行代码回显 LayUI表单数据回显 下拉列表select回显
热门文章
- C++_程序注释_以及_认识变量_输出变量_认识常量---C++语言工作笔记009
- 大数据之-Hadoop之HDFS_读数据流程_原理篇---大数据之hadoop工作笔记0069
- 大数据_Hbase-原理说明_大数据存储_垂直拆表_水平拆表_动态列扩展---Hbase工作笔记0003
- STM32工作笔记0061---通用定时器基本原理
- IntelliJ Idea学习笔记002---IDEA 全局搜索快捷键CTRL+SHIFT+F,不起作用
- 发现个特别合胃口的仓鼠、小鱼和计数器代码
- js控制数量包含截取
- CString、char*之间的相互转换
- C语言和设计模式(适配器模式)
- 一步一步写算法(之函数堆栈显示)