enthought / enthought/comtypes

Multiple instances of Autocad

Open
#520 9 comments 0 reactions 0 assignees View on GitHub
enhancement help wanted
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.