DCOM
Automation 桥将所有 UNO 对象映射成 Automation 对象。也就是说,所有这些对象都实现 IDispatch 接口。要访问远程接口,客户机和服务器必须能够封送该接口。Windows 已经提供对 IDispatch 的封送处理,因此,可以远程使用源自桥的所有对象。
要使 DCOM 工作,需要对客户机和服务器应用适当的安全设置。这可以通过设置适当的注册表项或以编程的方式调用程序中安全 API 函数来完成。办公软件不处理安全性,因此,只能通过不完全由办公软件安装程序设置的注册表设置进行确定。没有设定 AppID 项,它记录安全设置。不会产生任何问题,因为 dcomcnfg.exe 配置工具可以自动设置此项。
要远程访问服务管理器,客户机必须具有启动和访问权限。这些权限是 AppID 的子键,而且具有二进制值。可以使用 dcomcnfg 编辑这些值。同时,必须将服务管理器的身份设置为“交互式用户”。当通过远程激活服务管理器来启动办公软件时,办公软件以当前登录的用户(交互式用户)的帐号运行。
如果回调(办公软件调用客户机),客户机必须调整其安全设置,从而接受发来的办公软件调用请求。将作为 Automation 对象(而不是 UNO 组件)实现的侦听器对象以参数形式传送到 UNO 对象时,就会发生这种情况,而这又会调用这些对象。也可能由 Automation 桥产生回调,例如,使用 JScript Array 对象时。然后,桥通过其 IDispatchEx 接口修改 Array 对象。要获取接口,桥必须通过回调客户机来调用 QueryInterface。
要避免这些回调,可以使用 VBArray 对象和 Value Objects。
要设置客户机安全属性,请在客户机程序内使用安全 API,或者再次使用 dcomcnfg。API 的使用可能比较困难。修改注册表是最容易的方法,使用 dcomcnfg 简化了设定过程。这还会增强灵活性,因为管理员可以轻松地更改设定,而无需编辑源代码和重建客户机。但是,dcomcnfg 仅适用于 COM 服务器,而不适用于普通可执行程序。要使用 dcomcnfg,请将客户机代码放在一个可以在客户机计算机上注册的服务器中。这不仅适用于 exe 服务器,而且适用于进程内服务器,即 dll。当这些服务器处于远程状态时,具有一个 AppID 项,即它们具有 DllSurrogate 子项设定。要激活它们,需要一个实例化进程内服务器的附加可执行程序。初次调用服务器的一个接口时,DCOM 使用注册表中的值来初始化安全性,但是,只有在可执行程序没有事先调用 CoInitializeSecurity 的情况下,这才会起作用。
要运行 JScript 或 VBScript 程序,需要一个运行脚本的附加程序,即脚本控制器,例如,Windows Scripting Host (WSH)。这些控制器的问题是,自己调用 CoInitializeSecurity 可能会影响自身的安全设置。遇到这种情况,不会使用先前在注册表中为控制器设定的安全设置。另外,不必通过 dcomcnfg 配置控制器,因为它可能不是 COM 服务器。WSH(非远程 WSH)也是如此。
要去掉这些限制,需要在创建脚本引擎之前,编写一个应用安全设置的脚本控制器。这一过程非常耗时,而且需要具备一些引擎知识以及良好的编程技能。Windows Script Components (WSC) 使用比较简便。WSC 由一个包含 XML 的文件构成,而且可以将现有的 JScript 和 VBS 脚本放到各自的 XML 元素中。并提供了一个生成它的向导。必须注册 WSC,这可以通过 regsvr32.exe 或直接通过文件资源管理器中的上下文菜单来完成。要拥有一个 AppID 条目,请将组件声明为可以远程访问。这可以通过将 remotable 属性插入到 wsc 文件的注册元素中来完成:
<registration
description="writerdemo script component"
progid="dcomtest.writerdemo.WSC”
version="1.00"
classid="{90c5ca1a-5e38-4c6d-9634-b0c740c569ad}"
remotable="true">
注册 WSC 后,注册表中具有一个对应的 AppID 项。使用 dcomcnfg 对该组件应用所需的安全设置。要执行脚本,需要一个可执行程序。例如:
Option Explicit
Sub main()
Dim obj As Object
Set obj = CreateObject("dcomtest.writerdemo.wsc”)
obj.run
End Sub
在该示例中,脚本代码包含在运行函数中。下面是 wsc 文件的内容:
<?xml version="1.0"?>
<component>
<?component error="true" debug="true"?>
<registration
description="writerdemo script component"
progid="dcomtest.writerdemo.WSC”
version="1.00"
classid="{90c5ca1a-5e38-4c6d-9634-b0c740c569ad}"
remotable="true">
</registration>
<public>
<method name="run">
</method>
</public>
<script language="JScript">
<![CDATA[
var description = new jscripttest;
function jscripttest()
{
this.run = run;
}
function run()
{
var objServiceManager= new ActiveXObject("com.sun.star.ServiceManager”,"\\jl-1036");
var objCoreReflection= objServiceManager.createInstance("com.sun.star.reflection.CoreReflection");
var objDesktop= objServiceManager.createInstance("com.sun.star.frame.Desktop");
var objCoreReflection= objServiceManager.createInstance("com.sun.star.reflection.CoreReflection");
var args= new Array();
var objDocument= objDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, args);
var objText= objDocument.getText();
var objCursor= objText.createTextCursor();
objText.insertString( objCursor, "The first line in the newly created text document.\n", false);
objText.insertString( objCursor, "Now we're in the second line", false);
var objTable= objDocument.createInstance( "com.sun.star.text.TextTable");objTable.initialize( 4, 4);
objText.insertTextContent( objCursor, objTable, false);
var objRows= objTable.getRows();
var objRow= objRows.getByIndex( 0);
objTable.setPropertyValue( "BackTransparent", false);
objTable.setPropertyValue( "BackColor", 13421823);
objRow.setPropertyValue( "BackTransparent", false);
objRow.setPropertyValue( "BackColor", 6710932);
insertIntoCell( "A1","FirstColumn", objTable);
insertIntoCell( "B1","SecondColumn", objTable);
insertIntoCell( "C1","ThirdColumn", objTable);
insertIntoCell( "D1","SUM", objTable);
objTable.getCellByName("A2").setValue( 22.5);
objTable.getCellByName("B2").setValue( 5615.3);
objTable.getCellByName("C2").setValue( -2315.7);
objTable.getCellByName("D2").setFormula("sum <A2:C2>");objTable.getCellByName("A3").setValue( 21.5);
objTable.getCellByName("B3").setValue( 615.3);
objTable.getCellByName("C3").setValue( -315.7);
objTable.getCellByName("D3").setFormula( "sum <A3:C3>");objTable.getCellByName("A4").setValue( 121.5);
objTable.getCellByName("B4").setValue( -615.3);
objTable.getCellByName("C4").setValue( 415.7);
objTable.getCellByName("D4").setFormula( "sum <A4:C4>");
objCursor.setPropertyValue( "CharColor", 255);
objCursor.setPropertyValue( "CharShadowed", true);
objText.insertControlCharacter( objCursor, 0 , false);
objText.insertString( objCursor, " This is a colored Text - blue with shadow\n",false);
objText.insertControlCharacter( objCursor, 0, false );
var objTextFrame= objDocument.createInstance("com.sun.star.text.TextFrame”);
var objSize= createStruct("com.sun.star.awt.Size");
objSize.Width= 15000;
objSize.Height= 400;
objTextFrame.setSize( objSize);
objTextFrame.setPropertyValue( "AnchorType", 1);
objText.insertTextContent( objCursor, objTextFrame, false);
var objFrameText= objTextFrame.getText();
var objFrameTextCursor= objFrameText.createTextCursor();
objFrameText.insertString( objFrameTextCursor, "The first line in the newly created text frame.",false);
objFrameText.insertString(objFrameTextCursor, "With this second line the height of the frame raises.", false );
objFrameText.insertControlCharacter( objCursor, 0 , false);
objCursor.setPropertyValue( "CharColor", 65536);
objCursor.setPropertyValue( "CharShadowed", false);
objText.insertString( objCursor, " That's all for now !!", false );
function insertIntoCell( strCellName, strText, objTable)
{
var objCellText= objTable.getCellByName( strCellName);
var objCellCursor= objCellText.createTextCursor();
objCellCursor.setPropertyValue( "CharColor",16777215);
objCellText.insertString( objCellCursor, strText, false);
}
function createStruct( strTypeName)
{
var classSize= objCoreReflection.forName( strTypeName);
var aStruct= new Array();
classSize.createObject( aStruct);
return aStruct[0];
}
}
]]>
</script>
</component>
该 WSC 包含用 JScript 编写的 WriterDemo 示例。
| Content on this page is licensed under the Public Documentation License (PDL). |