3

Coming from the same background as the original poster in this thread, I wonder if anyone has had any success creating an Arc10 Add-In using IronPython.

I have been able to access ArcObjects via IronPython using the info in the linked thread, assorted blog postings, and a few posts on the ESRI forums. These neophyte attempts have all been run from the command line and I would to be able to gain access through either a toolbar or a button.

One thought that I had was to create the add-in using the .Net 3.5 template, add a python file, and then call a function in the python file from the button's C# file. It appears though that add-ins are not yet supported in .Net4?

Here is the code from the .cs file which controls button functionality.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
//I need to then add references to IronPython
using IronPython;
using IronPython.Hosting;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
namespace PyButtonTest
{
 public class ZoomToLayer : ESRI.ArcGIS.Desktop.AddIns.Button
 {
 public ZoomToLayer()
 {
 }
 protected override void OnClick()
 {
 var ipy = Python.CreateRuntime();
 dynamic test = ipy.UseFile("ZoomToLayer.py");
 test.ZoomToActiveLayerInTOC(); //Call this function in the py file
 ArcMap.Application.CurrentTool = null;
 }
 protected override void OnUpdate()
 {
 Enabled = ArcMap.Application != null;
 }
 }
}

As far as I can tell the Add-in format takes care of getting the application hook. I should then be able to, in the python file, after referencing and importing all of the necessary libraries get the map document with (I think?)

mxDoc = ArcMapUI.IMxDocument.ActiveView

From here I am stumped. Google has not turned up anything helpful. Has anyone else tried this? Got something to work? Do I need to wait until add-ins are supported in .Net4 to go this route?

asked Apr 15, 2011 at 12:22
2
  • ArcMap doesn't support .Net4 yet? ESRI is always so behind. Unfortunately, I haven't had the chance to even begin exploring ArcObjects yet (suddenly my GIS Analyst title extends to Web Development), but I wish you the best of luck with this! Although it would help if my manager didn't think that non-standard libraries were bad hoodoo. Commented Apr 15, 2011 at 17:49
  • If you're trying to run a Zoom to Selected Layer there was an example of how to do that in DOTNET for the 9.3 platform up on the resource center for a while. I have a version of it if you are interested. If that is your end goal with running python from a button. Commented Apr 15, 2011 at 19:26

1 Answer 1

2

So I'm hoping this helps. I was having an issue with the 3.5 framework a few weeks back, to the point that I couldn't build and populate a new geodatabase using straight up ArcObjects within my Add-in. However I could do all of that work from my python prototype. So what I ended up doing was building a wrapper method that just called my python directly (no iron python needed). I also have a method that tracks down the python executable path (which if memory serves, iron python needs anyway):

 public void RunPython(String pythonpath, String filename)
 {
 Process p = new Process();
 p.StartInfo.FileName = pythonpath;
 p.StartInfo.Arguments = "C:\\Users\\Luke\\workspace\\EclipseWorkspace\\GCWWPythonSVN\\src\\EditorUtilities\\SurveyLoader.py " //
 + '"' + filename + '"';
 p.StartInfo.UseShellExecute = true;
 p.StartInfo.CreateNoWindow = false;
 p.Start();
 p.WaitForExit();
 }
 public String FindPythonPath()
 {
 String pythondirectory = "";
 DriveInfo[] allDrives = DriveInfo.GetDrives();
 foreach (DriveInfo dirInfo in allDrives)
 {
 if (dirInfo.IsReady)
 {
 String[] driveDir = Directory.GetDirectories(dirInfo.Name);
 foreach (String dir in driveDir)
 {
 if (dir.Contains("Python"))
 {
 String[] directoryInfo = Directory.GetFiles(dir);
 if (directoryInfo.Length == 0)
 {
 String[] pythonFolder = Directory.GetDirectories(dir);
 foreach (String pyDir in pythonFolder)
 {
 String[] pyDirFiles = Directory.GetFiles(pyDir);
 foreach (String file in pyDirFiles)
 {
 if (file.Contains("python.exe"))
 {
 pythondirectory = file;
 break;
 }
 }
 }
 }
 else
 {
 String[] fileFolder = Directory.GetFiles(dir);
 foreach (String pyfile in directoryInfo)
 {
 if (pyfile.Contains("python.exe"))
 {
 pythondirectory = pyfile;
 break;
 }
 }
 }
 }
 }
 }
 if (!pythondirectory.Equals(""))
 {
 break;
 }
 }
 return pythondirectory;
 }

In my case I'm passing in the csv file that I'm parsing through with the python code. So you with the Add -in (or a COM hook for that matter), you should be able to pass the map document. My application ends up firing a python command line window from my click event, but I'm guessing that if you're firing off a python app with IP you're expecting the PVM to run anyway.

p.StartInfo.Arguments = "C:\Users\Luke\workspace\EclipseWorkspace\GCWWPythonSVN\src\EditorUtilities\SurveyLoader.py " // + '"' + filename + '"';

Hope this helps.

answered Apr 15, 2011 at 14:23
5
  • All those nested if statements really scare me o_0 I hope this is not production code. Tip: You could exit early with some of those if statements to avoid the massive nesting. Commented Apr 15, 2011 at 14:39
  • also I'm not sure just brute force searching for python would be very good. I'm pretty sure its location is stored in the registry. Commented Apr 15, 2011 at 14:44
  • the brute force bit is productional with another application, but it's due for a refactor and upgrade (that method works perfectly oddly enough) -- I'm having an issue with my synchronization component. and I personally HATE even thinking about mucking around with the registry. EVER. Commented Apr 15, 2011 at 16:08
  • The if nesting is numerous, but I find it pretty darn readable, regardless. "Optimized" code is usually what trips me up. Ah, the grace of ignorance. :) Commented Apr 15, 2011 at 17:46
  • in most cases the python location is stored in the environment path (for windows machines) as well. Commented May 11, 2013 at 15:46

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.