我使用示例代码在VB.Net中创建ActiveX-Exe COM服务器:
http://code.msdn.microsoft.com/windowsapps/VBExeCOMServer-74ecdb1c
当我从Active-X中调用GetCurrentProcessID时,它返回与调用应用程序相同的ID。
有人能告诉我这是自然的吗,还是我在封装ActiveX-Exe组件时做错了什么?
我是这样测试的:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
_MouseIndicator = New twsMouseIndicator.clsMouseIndicator
With _MouseIndicator
.ImagePath = "d:\dev\projects\osc\gui\autoclick\prog4.png"
.Size = 300
.Alpha = 155
.FollowMouse = True
.Active = True
End With
Dim iProcessIDOutOfProcID As Integer = _MouseIndicator.CurrentProcessID
Dim iCallerProcessID As Integer = GetCurrentProcessId()
If iProcessIDOutOfProcID = iCallerProcessID Then
MessageBox.Show("ProcIDs are the same, namely " & iCallerProcessID & ". This can not be right!")
Else
MessageBox.Show("Everything is okay.")
End If
End Sub在调用应用程序"GetCurrentProcessID“中,声明为
Module Module1
''' <summary>
''' Get current process ID.
''' </summary>
''' <returns></returns>
<DllImport("kernel32.dll")> _
Public Function GetCurrentProcessId() As UInt32
End Function
End Module在Out-Proc-COM-Server中,声明如下:
Public Function CurrentProcessID() As UInt32
Return NativeMethod.GetCurrentProcessId
End Function
Friend Class NativeMethod
''' <summary>
''' Get current process ID.
''' </summary>
''' <returns></returns>
<DllImport("kernel32.dll")> _
Friend Shared Function GetCurrentProcessId() As UInt32
End Function发布于 2014-10-02 06:04:46
我已经找到了一个在我的开发环境中工作的解决方案。我从这里中选取了OP的示例项目,在评论中引用了该示例。我已经创建了一个新的 outofproc.zip,我希望它能为OP工作。我沿途所发现和学到的东西的一些历史如下。
我重新构建了VBExeComServer项目(该项目安装并注册了COM可执行文件)。我尝试用通过caller实例化SimpleObject的方法来使用OP的CreateObject("VBExeCOMServer.SimpleObject")项目,它的挂起方式与OP在注释中描述的方式相同。我觉得很困惑。
然后,我决定更深入地研究VBExeComServer项目。这基本上是OP在他的问题中发布的一个样本。由于这个项目是已知的工作,它很可能是环保的东西。经过一些尝试和错误和几个谷歌搜索,我发现了这个关于StackOverflow的问题。虽然这个问题没有得到答案,但我觉得所提供的信息似乎与我所经历的有些相似。它特别指出:
我正试图让COM启动我的进程外.NET COM服务器.如果服务器进程是用x64编译的,那么它可以工作,但是如果我使用AnyCPU (这正是我想要的),那么挂起一段时间,最后在0x80080005 (CO_E_SERVER_EXEC_FAILURE)中失败。我怎么才能让这个起作用?
我发现hangs for a while的评论与我们看到的相当相似。当我试图使用Powershell实例化对象时,我也得到了相同的错误。尽管有迹象表明,他没有让它发挥作用,但我觉得有足够的证据来调查我们项目的设置。首先,VBExeComServer使用任意CPU作为平台类型。鉴于上面的节选,我决定修改项目,通过配置管理器创建'x64‘和'x86’平台选项。然后,我尝试构建x64,它未能注册可执行文件并构建类型库。我试过x86,它编译/注册了。我发现这个关于微软文章程序集的x64程序集使我走上了正确的轨道。特别是,它有以下指示:
为了解决这个问题,添加一个post build命令,使用以下步骤调用64位版本的RegAsm.exe。
我没有使用他们推荐的内容,因为它将项目限制为只构建x64。我决定通过查看构建平台类型来增强这个想法。如果是x64,我会像上面那样使用Framework64正则表达式。不幸的是,VBExeComServer项目(由MS制作)默认假定32位程序集,而不是64位程序集,因为它们在生成后事件中使用了32位regasm。最后我在post-build events中使用了这个
echo Generate and register type library.
if "$(PlatformName)" == "x64" (
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\regasm.exe /tlb "$(TargetPath)"
) else (
C:\Windows\Microsoft.NET\Framework\v2.0.50727\regasm.exe /tlb "$(TargetPath)"
)
echo Register the component.
if "$(PlatformName)" == "x64" (
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\regasm.exe "$(TargetPath)"
) else (
C:\Windows\Microsoft.NET\Framework\v2.0.50727\regasm.exe "$(TargetPath)"
)
echo Generate and register type library.然后我尝试为platform Any CPU构建,它正确地编译和注册。然后我做了x86,然后构建了x64。所有这些都是按预期建造和注册的。请注意,在构建COM服务器时,我将Visual作为administrator运行,以便COM注册过程具有在整个注册表系统范围内更新注册表系统的适当权限。
接下来,我进入了任务管理器(这很重要)。我删除了所有可能一直存在的旧的VBExeComServer进程。人们可以求助于重新启动窗户来确保。未能从内存中清除旧的可执行文件可能会导致未定义的行为。
那么现在caller (客户端)代码可以工作了吗?我把项目装填好了,运行得很好。我甚至对caller项目进行了修改,将其构建为x86、x64和Any CPU平台,并且它们都起了作用。他们都找到了一个与客户端进程的processid不相等的SimpleObject。
特别注意事项:如果您希望caller项目正常工作,并且在64位系统上使用平台类型Any CPU,或者使用平台类型x64,则需要确保如上所述构建64位VBExeComServer。如果不这样做,就会导致我们所经历的悬念。
接下来,我恢复了OP的早期绑定代码:
Private _Com As VBExeCOMServer.SimpleObject
_Com = New VBExeCOMServer.SimpleObject我预感到这不会通过COM/Interop加载出的proc-服务器。我是对的。当我恢复这些行时,我能够运行caller程序,但是Process IDs是相同的。原因是VB.Net COM对象是作为碰巧提供进程外COM服务器的程序集创建的。但是,如果您试图将EXE作为引用(或TLB)导入,它会告诉您不能这样做,因为它是一个CLR程序集。当您这样做时,_Com As VBExeCOMServer.SimpleObject VB.Net将绕过所有COM/Interop代码,并将该可执行文件添加为具有直接访问对象的程序集。
其他人可能有一个想法,如何使这一工作的另一种方式。以下使用后期绑定
Private _Com As Object
_Com = CreateObject("VBExeCOMServer.SimpleObject")CreateObject通过COM/Interop强制创建VBExeCOMServer.SimpleObject。如果它还没有运行,我们的COM服务器就会启动。一旦服务器运行以处理我们的请求,一个新的SimpleObject将被实例化。
前面引用的我的outofproc.zip文件已经用上面提到的所有项目进行了修改。至少在我的环境中,它确实能像预期的那样工作。
https://stackoverflow.com/questions/25983730
复制相似问题