+ Reply to Thread
Results 1 to 6 of 6

Thread: ArcMap 10, ArcObjects, and Python: very cool, but help with a couple of problems?

  1. #1
    Ti Crossman
    Join Date
    Aug 2010
    Posts
    17
    Points
    0
    Answers Provided
    0


    0

    Default ArcMap 10, ArcObjects, and Python: very cool, but help with a couple of problems?

    VITALS: ArcGIS 10.0 - ArcView, Python 2.6.5, comtypes 0.6.2

    I am writing an external Python script that needs to access the running ArcMap 10 application; therefore, I am getting my app reference through the AppROT object, which is working fine, as far as that goes. So, here are my problems/questions:

    1) What object type is returned when I execute the line pApp=pAppROT.Item(i)? I definitely get an IApplication for ArcMap but on what object exactly? I thought it was IApplication in the esriArcMapUI.olb, but that may not be the case ... esriFramework.olb maybe? [BTW, pAppROT is the IAppROT interface on the AppROT object.] It makes a difference, because I later QI to IMxDocument and get an error that the module (esriArcMapUI) has no attribute IMxDocument. This may all relate to my 2nd question:

    2) I am building Python wrappers for ESRI olb's on the fly using the GetModule function in comtypes. The problem is that wrappers are not being built for all of the olb's I specify, or rather the wrapper .py modules (the ones with the long GUID names) are empty. esriFramework, esriGeometry, esriSystem, and esriSystemUI build just fine. esriArcMapUI, esriCarto, and esriGeoDatabase do not build. Has anyone else had this problem? If so, how did you fix it ... if you did , that is?

    Thank you all for the help.

    -- Ti

  2. #2
    Frank Perks
    Join Date
    Apr 2010
    Posts
    59
    Points
    5
    Answers Provided
    0


    0

    Default Re: ArcMap 10, ArcObjects, and Python: very cool, but help with a couple of problems

    1. Your first problem is related to you second:

    2. If you run the following (this will generate wrappers for every ESRI com lib):

    Code:
    import os
    import comtypes.client
    # change com_dir to whatever it is for you
    com_dir = r'C:\Program Files (x86)\ArcGIS\Desktop10.0\com'
    coms = [os.path.join(com_dir, x) for x in os.listdir(com_dir) if os.path.splitext(x)[1].upper() == '.OLB']
    map(comtypes.client.GetModule, coms)
    
    # check add whatever you want here.
    import comtypes.gen.esriArcMapUI
    import comtypes.gen.esriGeodatabase
    
    print dir(comtypes.gen.esriArcMapUI)
    Do you get anything from the dir?

    If not then run this:

    Code:
    import logging
    # grab rootlogger
    _loggy = logging.getLogger()
    _loggy.setLevel(logging.DEBUG)
    _loggy.addHandler(logging.FileHandler("derpdebug.log"))
    import os
    import comtypes.client
    # change com_dir to whatever it is for you
    com_dir = r'C:\Program Files (x86)\ArcGIS\Desktop10.0\com'
    coms = [os.path.join(com_dir, x) for x in os.listdir(com_dir) if os.path.splitext(x)[1].upper() == '.OLB']
    map(comtypes.client.GetModule, coms)
    
    # check add whatever you want here.
    import comtypes.gen.esriArcMapUI
    import comtypes.gen.esriGeodatabase
    
    print dir(comtypes.gen.esriArcMapUI)
    There should now be a derpdebug.log file now (where ever you ran it from), open it up and look for, anything that indicates an error, also make sure you see the GetModule call for esriArcMapUI.

    Worst case, delete everything in <PYTHON_DIR>\comtypes\gen directory (python_dir is your python installation path).

    If still this does not work, let me know.

  3. #3
    Ti Crossman
    Join Date
    Aug 2010
    Posts
    17
    Points
    0
    Answers Provided
    0


    0

    Default Re: ArcMap 10, ArcObjects, and Python: very cool, but help with a couple of problems

    Frank,

    Thank you so much for your help. Your solutions worked like a charm. When I ran your script, the dir listed everything in the __dict__ of esriArcMapUI, as it should. esriArcMapUI.py was intact. With help from the person who wrote the example code that I used as a base, I have discovered that the comtypes generation of wrappers for ArcObjects occasionally fails, creating blank wrapper files. This seems to happen when a wrapper file already exists and GetModule() is called to build it again. I tested the wrapping process many more times, with both existing wrappers and a cleared out gen cache directory. I got a failure once, and that was for an existing wrapper. No failures for an empty cache. Also, the failures all produced readable but empty files. I have not encountered any instances of missing wrappers (where there should be one) or of corrupted, unreadable wrappers. I did also run your second, debug script quite a few times, and dir() reported as expected. The debug logs also showed no errors. So, I have modified my code to check for existing (the more secure open(filepath) way) wrappers and whether those existing modules are blank or not before I make any calls to GetModule(). Works great. I'll just be sure to rerun the wrapping process after ArcObjects updates. Thanks, again, Frank. I only wish I could give you some MVP points. Grrrr.

    Cheers,

    Ti
    GIS Specialist
    Durham, NH

  4. #4
    Frank Perks
    Join Date
    Apr 2010
    Posts
    59
    Points
    5
    Answers Provided
    0


    0

    Default Re: ArcMap 10, ArcObjects, and Python: very cool, but help with a couple of problems

    Quote Originally Posted by celticflute View Post
    Frank,

    Thank you so much for your help. Your solutions worked like a charm. When I ran your script, the dir listed everything in the __dict__ of esriArcMapUI, as it should. esriArcMapUI.py was intact. With help from the person who wrote the example code that I used as a base, I have discovered that the comtypes generation of wrappers for ArcObjects occasionally fails, creating blank wrapper files. This seems to happen when a wrapper file already exists and GetModule() is called to build it again. I tested the wrapping process many more times, with both existing wrappers and a cleared out gen cache directory. I got a failure once, and that was for an existing wrapper. No failures for an empty cache. Also, the failures all produced readable but empty files. I have not encountered any instances of missing wrappers (where there should be one) or of corrupted, unreadable wrappers. I did also run your second, debug script quite a few times, and dir() reported as expected. The debug logs also showed no errors. So, I have modified my code to check for existing (the more secure open(filepath) way) wrappers and whether those existing modules are blank or not before I make any calls to GetModule(). Works great. I'll just be sure to rerun the wrapping process after ArcObjects updates. Thanks, again, Frank. I only wish I could give you some MVP points. Grrrr.

    Cheers,

    Ti
    GIS Specialist
    Durham, NH
    The way comtypes generates modules is a goldmine of horrors. GetModule only checks if the module is importable (via importerror), and does not check if the module actually finished generation. Technically it should hold off of writing the modules until all other linked modules are finished processing, sadily it does not (this bug has been in their bug tracker for quite awhile last time i checked.)

    If you are deploying a script that uses comtypes, the safest way is to modify the distutils setup.py file(if your not using one then make a script that is run once, when the script is installed). So:

    1. Nuke the comtypes.gen folder
    2. call GetModule() on all of the comlibs in the ArcGIS/com folder.

    This prevents the need for GetModule() to be used within your actual program. Which hopefully makes things a little easier.

  5. #5
    Phil Morefield
    Join Date
    Apr 2010
    Posts
    133
    Points
    59
    Answers Provided
    8


    0

    Default Re: ArcMap 10, ArcObjects, and Python: very cool, but help with a couple of problems

    Frank,

    I'm only just learning ArcObjects, and I'm hoping you can throw a little advice my way. Based on what I've read so far, I thought the following would work:

    Code:
    import arcpy
    import comtypes
    import comtypes.client
    import comtypes.gen.esriDataSourcesNetCDF
    
    ws_factory = comtypes.client.CreateObject("esriDataSourcesNetCDF.NetCDFWorkspaceFactory", interface = esriDataSourcesNetCDF.INetCDFWorkspaceFactory)
    However, this throws an error since there is "no attribute 'INetCDFWorkspaceFactory'. As I understand it, Step 1 is to create a workspace factory. Step 2 is to create the workspace. And Step 3 is to instantiate the file of interest (in this case a NetCDF file) so I can play with the data.

    Can you steer me back on course?

  6. #6
    Mike Hunter
    Join Date
    Apr 2010
    Posts
    68
    Points
    70
    Answers Provided
    11


    0

    Default Re: ArcMap 10, ArcObjects, and Python: very cool, but help with a couple of problems

    Try this. It should work:


    import comtypes.gen.esriDataSourcesNetCDF as esriDataSourcesNetCDF
    import comtypes.gen.esriGeoDatabase as esriGeoDatabase

    ws_factory = comtypes.client.CreateObject("esriDataSourcesNetCDF.NetCDFWorkspaceFactory", interface = esriGeoDatabase.IWorkspaceFactory)

    In AO, a class may be in 1 library, and an interface to that class may be in another. Also, do the imports like I did above--it will help your IDE to follow what's going on and help you with autocompletes.

    good luck,
    Mike
    Last edited by mahunter243; 12-09-2010 at 06:44 PM.

+ Reply to Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts