Proxy 在VB6中创建在运行时指定服务器的非排队远程COM对象

Proxy 在VB6中创建在运行时指定服务器的非排队远程COM对象,proxy,com,vb6,Proxy,Com,Vb6,我在两台远程服务器上的COM应用程序中安装了COM+dll。我已经从其中一台服务器导出了一个非排队代理,并将其安装在客户机上 我希望能够指定COM对象在运行时在哪个远程服务器上实例化-代理安装包含我从中导出代理的机器的远程服务器名称,因此只要在客户端上创建代理,就会始终调用我从中导出的机器,因为它是代理属性的一部分 代理未排队,因此我无法使用路径名调用GetObject的方法,如queue:ComputerName=Server01/new:ComClass.Class 对于总是调用从中导出的远

我在两台远程服务器上的COM应用程序中安装了COM+dll。我已经从其中一台服务器导出了一个非排队代理,并将其安装在客户机上

我希望能够指定COM对象在运行时在哪个远程服务器上实例化-代理安装包含我从中导出代理的机器的远程服务器名称,因此只要在客户端上创建代理,就会始终调用我从中导出的机器,因为它是代理属性的一部分

代理未排队,因此我无法使用路径名调用
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