我正在使用.Net编写一个Windows窗体应用程序,以列出所有运行中的第三方CAD/CAM软件实例(在本例中为CATIA),并允许用户选择其中一个来执行一些自动化任务。为了执行自动化任务,我需要获取特定实例的COM对象-与GetObject()相比,后者给我一个非特定的COM实例。是否有一种方法可以使用窗口句柄或其他方法获取特定的COM实例?
更新: 正如Raymond所说,对于所有COM对象没有单一的解决方案;但是,我成功地使用以下代码获取CATIA COM对象(该代码使用ROT来填充一个列表,其中包含所有CATIA COM实例的名称):
然而,所有 CATIA 实例都指向第一个加载的 CATIA 应用程序。不知道为什么,有人知道吗?
更新: 正如Raymond所说,对于所有COM对象没有单一的解决方案;但是,我成功地使用以下代码获取CATIA COM对象(该代码使用ROT来填充一个列表,其中包含所有CATIA COM实例的名称):
<DllImport("user32.dll", CharSet:=CharSet.Auto)> Private Shared Sub GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) End Sub
<DllImport("ole32.dll", ExactSpelling:=True, PreserveSig:=False)> Private Shared Function GetRunningObjectTable(ByVal reserved As Int32) As IRunningObjectTable End Function
<DllImport("ole32.dll", CharSet:=CharSet.Unicode, ExactSpelling:=True, PreserveSig:=False)> Private Shared Function CreateItemMoniker(ByVal lpszDelim As String, ByVal lpszItem As String) As IMoniker End Function
<DllImport("ole32.dll", ExactSpelling:=True, PreserveSig:=False)> Private Shared Function CreateBindCtx(ByVal reserved As Integer) As IBindCtx End Function
Try
Dim ROTObject As Object = Nothing
Dim runningObjectTable As IRunningObjectTable
Dim monikerEnumerator As IEnumMoniker = Nothing
Dim monikers(1) As IMoniker
runningObjectTable = GetRunningObjectTable(0)
runningObjectTable.EnumRunning(monikerEnumerator)
monikerEnumerator.Reset()
Dim numFetched As IntPtr = New IntPtr()
While (monikerEnumerator.Next(1, monikers, numFetched) = 0)
Dim ctx As IBindCtx
ctx = CreateBindCtx(0)
Dim runningObjectName As String = ""
monikers(0).GetDisplayName(ctx, Nothing, runningObjectName)
runningObjectName = runningObjectName.ToUpper
If (Not runningObjectName.Equals("")) Then
Dim runningObjectIns As Object = Nothing
runningObjectTable.GetObject(monikers(0), runningObjectIns)
'Check if object is a Catia object
Try
Dim catiaIns As INFITF.Application = Nothing
catiaIns = DirectCast(runningObjectIns, INFITF.Application)
ListCATIA.Items.Add(catiaIns.Windows.Count)
Catch Exc As Exception
MessageBox.Show(Exc.ToString())
End Try
End If
End While
Catch Exc As Exception
Throw Exc
End Try
然而,所有 CATIA 实例都指向第一个加载的 CATIA 应用程序。不知道为什么,有人知道吗?