enthought / enthought/comtypes
Multiple instances of Autocad
- Dominant language
- Python
- Stars
- 345
- Forks
- 105
- PR merge metrics
- No merged PRs in 30d
Description
Hello!
I know, that if Autocad is already running, we can use `comtypes.client.GetActiveObject`:
```python
import comtypes.client as cc
app = cc.GetActiveObject("AutoCAD.Application")
```
But what to do, if multiple instances of Autocad is running?
I [found](https://adndevblog.typepad.com/autocad/2013/12/accessing-com-applications-from-the-running-object-table.html) the code to solve this issue, but it's in C#:
```c#
[DllImport("ole32.dll")]
static extern int CreateBindCtx(
uint reserved,
out IBindCtx ppbc);
[DllImport("ole32.dll")]
public static extern void GetRunningObjectTable(
int reserved,
out IRunningObjectTable prot);
// Requires Using System.Runtime.InteropServices.ComTypes
// Get all running instance by querying ROT
private List GetRunningInstances(string[] progIds)
{
List clsIds = new List();
// get the app clsid
foreach (string progId in progIds)
{
Type type = Type.GetTypeFromProgID(progId);
if(type != null)
clsIds.Add(type.GUID.ToString().ToUpper());
}
// get Running Object Table ...
IRunningObjectTable Rot = null;
GetRunningObjectTable(0, out Rot);
if (Rot == null)
return null;
// get enumerator for ROT entries
IEnumMoniker monikerEnumerator = null;
Rot.EnumRunning(out monikerEnumerator);
if (monikerEnumerator == null)
return null;
monikerEnumerator.Reset();
List instances = new List();
IntPtr pNumFetched = new IntPtr();
IMoniker[] monikers = new IMoniker[1];
// go through all entries and identifies app instances
while (monikerEnumerator.Next(1, monikers, pNumFetched) == 0)
{
IBindCtx bindCtx;
CreateBindCtx(0, out bindCtx);
if (bindCtx == null)
continue;
string displayName;
monikers[0].GetDisplayName(bindCtx, null, out displayName);
foreach (string clsId in clsIds)
{
if (displayName.ToUpper().IndexOf(clsId) > 0)
{
object ComObject;
Rot.GetObject(monikers[0], out ComObject);
if (ComObject == null)
continue;
instances.Add(ComObject);
break;
}
}
}
return instances;
}
void TestROT()
{
// Look for acad 2009 & 2010 & 2014
string[] progIds =
{
"AutoCAD.Application.17.2",
"AutoCAD.Application.18",
"AutoCAD.Application.19.1"
};
List instances = GetRunningInstances(progIds);
foreach (object acadObj in instances)
{
try
{
// do some stuff ...
}
catch
{
}
}
}
```
I know it's possible to translate the C# code above to Python, but I don't know C# to do so. Anybody know it to translate, please?
Contributor guide
Assessment
This issue has not been assessed yet.