Proxy 在VB6中创建在运行时指定服务器的非排队远程COM对象
我在两台远程服务器上的COM应用程序中安装了COM+dll。我已经从其中一台服务器导出了一个非排队代理,并将其安装在客户机上 我希望能够指定COM对象在运行时在哪个远程服务器上实例化-代理安装包含我从中导出代理的机器的远程服务器名称,因此只要在客户端上创建代理,就会始终调用我从中导出的机器,因为它是代理属性的一部分 代理未排队,因此我无法使用路径名调用Proxy 在VB6中创建在运行时指定服务器的非排队远程COM对象,proxy,com,vb6,Proxy,Com,Vb6,我在两台远程服务器上的COM应用程序中安装了COM+dll。我已经从其中一台服务器导出了一个非排队代理,并将其安装在客户机上 我希望能够指定COM对象在运行时在哪个远程服务器上实例化-代理安装包含我从中导出代理的机器的远程服务器名称,因此只要在客户端上创建代理,就会始终调用我从中导出的机器,因为它是代理属性的一部分 代理未排队,因此我无法使用路径名调用GetObject的方法,如queue:ComputerName=Server01/new:ComClass.Class 对于总是调用从中导出的远
GetObject
的方法,如queue:ComputerName=Server01/new:ComClass.Class
对于总是调用从中导出的远程服务器的非排队代理,我只使用CreateObject(objectName)
,它将使用代理属性中的远程服务器名称
经过一番搜索,我找到了一个解决方案(在我下面的自我回答中),但是在VB6中有没有一种更简单的方法可以不用使用ole32.dll
函数来实现这一点
编辑:在测试@Bob77在评论中提出的解决方案后,使用server name参数调用CreateObject
无效。仅使用概述的CreateRemoteObject
方法实际调用指定服务器上的COM组件
这可能是因为客户端调用来自IIS进程,并且远程服务器COM+应用程序的用户标识不同。这可以使用
ole32.dll
库中的CoCreateInstanceEx
函数来完成
首先从ole32.dll
声明所需的函数和相应的数据结构:
Private Type SERVER_STRUCTURE
reserved1 As Long
pServer As Long
AuthInfo As Long
reserved2 As Long
End Type
Private Type MULTI_QI
pIID As Long
pInterface As Object
hResult As Long
End Type
Private Declare Function CLSIDFromProgID Lib "ole32.dll" _
(progid As Any, clsid As Any) As Long
Private Declare Function OleInitialize Lib "ole32.dll" _
(ByVal Nullptr As Long) As Long
Private Declare Function CoCreateInstanceEx Lib "ole32.dll" _
(clsid As Any, ByVal pUnkOuter As Long, _
ByVal Context As Long, server As SERVER_STRUCTURE, _
ByVal nElems As Long, mqi As MULTI_QI) As Long
然后,我使用此函数,该函数接受对象名和服务器名,并返回对象的实例,该实例将是所需服务器的代理:
Private Function CreateRemoteObject(ByVal ObjectName As String, _
ByVal ByVal serverName As String) As Object
Dim clsid(256) As Byte
Dim progid() As Byte
Dim server() As Byte
Dim queryInterface As MULTI_QI
Dim serverStructure As SERVER_STRUCTURE
Dim refiid(16) As Byte
Dim longReturnCode As Long
Dim errorString As String
errorString = ""
GetInterfaceIDforIDispatch refiid() ' set an interface ID for IDispatch
queryInterface.pIID = VarPtr(refiid(0)) ' point to the interface ID
progid = ObjectName & Chr$(0) ' specify the object to be launched
server = serverName & Chr$(0) ' specify the server
OleInitialize 0 ' initialise OLE
longReturnCode = CLSIDFromProgID(progid(0), clsid(0)) ' get the CLSID for the object
If longReturnCode <> 0 Then
errorString = "Unable to obtain CLSID from progid " & ObjectName
App.LogEvent errorString, vbLogEventTypeError
Exit Function
End If
' point to server name and invoke a remote instance of the desired object
serverStructure.pServer = VarPtr(server(0))
longReturnCode = CoCreateInstanceEx(clsid(0), 0, 16, serverStructure, 1, queryInterface)
If longReturnCode <> 0 Then
errorString = "CoCreateInstanceEx failed with error code " & Hex$(longReturnCode)
App.LogEvent errorString, vbLogEventTypeError
Exit Function
End If
' Pass back object ref
Set CreateRemoteObject = queryInterface.pInterface
End Function
Private Sub GetInterfaceIDforIDispatch(p() As Byte)
' fills in the well-known IID for IDispatch into the byte array p.
p(1) = 4
p(2) = 2
p(8) = &HC0
p(15) = &H46
End Sub
Private函数CreateRemoteObject(ByVal ObjectName作为字符串_
ByVal ByVal服务器名(字符串形式)作为对象
Dim clsid(256)作为字节
Dim progid()作为字节
Dim server()作为字节
模糊的查询接口,如MULTI_QI
Dim serverStructure作为服务器结构
Dim refiid(16)作为字节
Dim longReturnCode尽可能长
Dim errorString作为字符串
errorString=“”
GetInterfaceIDiforIDispatch refiid()'设置IDispatch的接口ID
queryInterface.pIID=VarPtr(refid(0))'指向接口ID
progid=ObjectName&Chr$(0)'指定要启动的对象
server=serverName&Chr$(0)'指定服务器
OleInitialize 0'初始化OLE
longReturnCode=CLSIDFromProgID(progid(0),clsid(0))'获取对象的clsid
如果返回代码为0,则
errorString=“无法从progid获取CLSID”&ObjectName
App.LogEvent errorString,vbLogEventTypeError
退出功能
如果结束
'指向服务器名称并调用所需对象的远程实例
serverStructure.pServer=VarPtr(服务器(0))
longReturnCode=CoCreateInstanceEx(clsid(0)、0、16、服务器结构、1、查询接口)
如果返回代码为0,则
errorString=“CoCreateInstanceEx失败,错误代码为”&Hex$(longReturnCode)
App.LogEvent errorString,vbLogEventTypeError
退出功能
如果结束
'传递回对象引用
设置CreateRemoteObject=queryInterface.pInterface
端函数
私有子getInterfaceIDiforIDispatch(p()作为字节)
'将IDispatch的已知IID填充到字节数组p中。
p(1)=4
p(2)=2
p(8)=&HC0
p(15)=&H46
端接头
这可以使用ole32.dll
库中的CoCreateInstanceEx
函数来完成
首先从ole32.dll
声明所需的函数和相应的数据结构:
Private Type SERVER_STRUCTURE
reserved1 As Long
pServer As Long
AuthInfo As Long
reserved2 As Long
End Type
Private Type MULTI_QI
pIID As Long
pInterface As Object
hResult As Long
End Type
Private Declare Function CLSIDFromProgID Lib "ole32.dll" _
(progid As Any, clsid As Any) As Long
Private Declare Function OleInitialize Lib "ole32.dll" _
(ByVal Nullptr As Long) As Long
Private Declare Function CoCreateInstanceEx Lib "ole32.dll" _
(clsid As Any, ByVal pUnkOuter As Long, _
ByVal Context As Long, server As SERVER_STRUCTURE, _
ByVal nElems As Long, mqi As MULTI_QI) As Long
然后,我使用此函数,该函数接受对象名和服务器名,并返回对象的实例,该实例将是所需服务器的代理:
Private Function CreateRemoteObject(ByVal ObjectName As String, _
ByVal ByVal serverName As String) As Object
Dim clsid(256) As Byte
Dim progid() As Byte
Dim server() As Byte
Dim queryInterface As MULTI_QI
Dim serverStructure As SERVER_STRUCTURE
Dim refiid(16) As Byte
Dim longReturnCode As Long
Dim errorString As String
errorString = ""
GetInterfaceIDforIDispatch refiid() ' set an interface ID for IDispatch
queryInterface.pIID = VarPtr(refiid(0)) ' point to the interface ID
progid = ObjectName & Chr$(0) ' specify the object to be launched
server = serverName & Chr$(0) ' specify the server
OleInitialize 0 ' initialise OLE
longReturnCode = CLSIDFromProgID(progid(0), clsid(0)) ' get the CLSID for the object
If longReturnCode <> 0 Then
errorString = "Unable to obtain CLSID from progid " & ObjectName
App.LogEvent errorString, vbLogEventTypeError
Exit Function
End If
' point to server name and invoke a remote instance of the desired object
serverStructure.pServer = VarPtr(server(0))
longReturnCode = CoCreateInstanceEx(clsid(0), 0, 16, serverStructure, 1, queryInterface)
If longReturnCode <> 0 Then
errorString = "CoCreateInstanceEx failed with error code " & Hex$(longReturnCode)
App.LogEvent errorString, vbLogEventTypeError
Exit Function
End If
' Pass back object ref
Set CreateRemoteObject = queryInterface.pInterface
End Function
Private Sub GetInterfaceIDforIDispatch(p() As Byte)
' fills in the well-known IID for IDispatch into the byte array p.
p(1) = 4
p(2) = 2
p(8) = &HC0
p(15) = &H46
End Sub
Private函数CreateRemoteObject(ByVal ObjectName作为字符串_
ByVal ByVal服务器名(字符串形式)作为对象
Dim clsid(256)作为字节
Dim progid()作为字节
Dim server()作为字节
模糊的查询接口,如MULTI_QI
Dim serverStructure作为服务器结构
Dim refiid(16)作为字节
Dim longReturnCode尽可能长
Dim errorString作为字符串
errorString=“”
GetInterfaceIDiforIDispatch refiid()'设置IDispatch的接口ID
queryInterface.pIID=VarPtr(refid(0))'指向接口ID
progid=ObjectName&Chr$(0)'指定要启动的对象
server=serverName&Chr$(0)'指定服务器
OleInitialize 0'初始化OLE
longReturnCode=CLSIDFromProgID(progid(0),clsid(0))'获取对象的clsid
如果返回代码为0,则
errorString=“无法从progid获取CLSID”&ObjectName
App.LogEvent errorString,vbLogEventTypeError
退出功能
如果结束
'指向服务器名称并调用所需对象的远程实例
serverStructure.pServer=VarPtr(服务器(0))
longReturnCode=CoCreateInstanceEx(clsid(0)、0、16、服务器结构、1、查询接口)
如果返回代码为0,则
errorString=“CoCreateInstanceEx失败,错误代码为”&Hex$(longReturnCode)
App.LogEvent errorString,vbLogEventTypeError
退出功能
如果结束
'传递回对象引用
设置CreateRemoteObject=queryInterface.pInterface
端函数
私有子getInterfaceIDiforIDispatch(p()作为字节)
'将IDispatch的已知IID填充到字节数组p中。
p(1)=4
p(2)=2
p(8)=&HC0
p(15)=&H46
端接头
为什么不在CreateObject
调用的第二个参数中提供服务器名称?这就是它的目的。@Bob77:IB