5

I've developed Add-in tools (with Windows dialog GUIs) for ArcMap which work fine, but I would also like to be able to call these directly (passing in parameters so I won't need to display the dialog) from either a Model Workflow or a Python Script.

Is this possible ?

As a workaround I've tried using inter-process coms (via a named pipe) with a worker task / thread and this works right up to the point where I attempt to store changes - when ArcMap itself goes legs-up (I'm guessing maybe a lock issue?).

  • More likely a thread issue causing ArcMap to go legs-up.. ArcMap is a single thread process and its objects are not thread safe. Calling from python is discussed gis.stackexchange.com/questions/129456/… you should be able to call a public Execute method within your code with ICommandItem.Execute. – Michael Stimson Aug 23 '17 at 1:02
  • Okay - that makes sense (threads).How am I getting the ICommandItem for the addin when it's on a custom toolbar ? – Scott Quinn Aug 23 '17 at 3:00
  • ICommandBars.Find('ID_of_your_Code',False,True) resources.arcgis.com/en/help/arcobjects-net/componenthelp/… make sure your code has a public function to locate or it will not be found. – Michael Stimson Aug 23 '17 at 3:02
  • Or it might be simpler to create an interface as a GP tool (example desktop.arcgis.com/en/arcobjects/latest/java/…) which references your addin dll and call that from python. There is an older example in .net resources.esri.com/help/9.3/ArcGISEngine/dotnet/… – Michael Stimson Aug 23 '17 at 3:21
  • Thanks @MichaelStimson. RE: Comment 1: So that should work although I'd rather a method that doesn't tie me to a specific command toolbar (users have a way of messing with bars and moving buttons). RE Comment 2 - Hmmm ... interesting ... it's certainly going to be a fun afternoon of reading to get my head around all that - one thing, that's for VS 2005 and ArcMap 9.3, is that still valid with 10.x ? I'm surprised this isn't easier and more common esp. considering the limitations and problems with Python ?! – Scott Quinn Aug 23 '17 at 4:23
3
+100

So yes this is possible (many thanks to Michael Stimson for his help - the solution is basically in his comments, I'm just putting it all together here).

On the Python Side:

You'll need imports for the usual suspects (sys, os, and arcpy).

Get the COM functions you'll need from the "comtypes" library for Python (Google it) ... and import the framework while you're at it.

from comtypes.client import GetModule, CreateObject
import comtypes.gen.esriFramework

Load the framework COM module

modFramework = GetModule(<Your ArcGis Path> + r"com\esriFramework.olb") 

Create the app

pApp = CreateObject(modFramework.AppROT, interface=modFramework.IAppROT)

From it get a pointer to the document (NB: You want the Doc not the MXDoc)

pDoc = pApp.Item(0).Document.QueryInterface(modFramework.IDocument)  

Form there I got the Command Bars (could probably have skipped this).

pCmdBars = pDoc.CommandBars.QueryInterface(modFramework.ICommandBars)

Use the CommandBars "Find" to get a pointer to your Addin

pAddIn = pCmdBars.Find(<Your Addin Name>)

I used the "Tag" field to pass some params to the addin (optional)

pAddIn.Tag = <Some data (e.g. parameters) you want to pass to the addin>

Then execute (start) the addin

pAddIn.Execute()

If your addin is a "Button" that will call "OnClick".

On the C# side:

You don't need to do much if anything here. All I did was get the command bar and extract the Tag text (which I'd packed params into).

ICommandBars commandBars = ArcMap.Application.Document.CommandBars;
ICommandItem item = commandBars.Find(<Your Addin Name>);
item.Tag *<-- text is here* 

It's convoluted, but that's one way to do it (there may be others).

Cheers,

Scott

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.