Get Pro install folder location from Python

1094
6
Jump to solution
06-28-2017 09:53 AM
curtvprice
MVP Esteemed Contributor

Hi all, I have a puzzle for you today. I am trying to get the ArcGIS Pro install folder from Python.  I am open to suggestions on how to accomplish this task, but the following approach should work (and works for me with Desktop, although I usually use os.environ["AGSDESKTOPJAVA"] instead).

  • I don't want to use arcpy.GetInstallInfo() because I want to find out where the install is before I take the time to import arcpy.
  • We install in a non-standard location to avoid spaces in the path.  

Here is my attempt:

D:\Users\jwpowell>C:\Python27\ArcGIS10.4\python.exe
Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import _winreg
>>> with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
...                      r"SOFTWARE\ESRI\ArcGISPro") as key:
...     pro_path = _winreg.QueryValueEx(key, "InstallDir")[0]
...
Traceback (most recent call last):
 File "<stdin>", line 2, in <module>
WindowsError: [Error 2] The system cannot find the file specified‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

And yet, I can see this key with reg query fine:

D:\Users\jwpowell>reg query HKLM\SOFTWARE\ESRI\ArcGISPro /v InstallDir

HKEY_LOCAL_MACHINE\SOFTWARE\ESRI\ArcGISPro
 InstallDir REG_SZ C:\ArcGIS\Pro\‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

See, it works in Desktop. 

>>> with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
...                      r"SOFTWARE\WOW6432Node\ESRI\ArcGIS") as key:
...     dt_path = _winreg.QueryValueEx(key, "InstallDir")[0]
...
>>> dt_path
u'C:\\Program Files (x86)\\Common Files\\ArcGIS\\'

Is this a x64/x32 thing?

0 Kudos
1 Solution

Accepted Solutions
JoshuaBixby
MVP Esteemed Contributor

If I run your code, or equivalent code, from Pro Python installation; it works fine.  I think the issue is that you are using a 32-bit Python interpreter to access the 64-bit space in the registry.  The following should point you in the right direction:  Change 64bit Registry from 32bit Python - Stack Overflow 

View solution in original post

6 Replies
BruceHarold
Esri Regular Contributor

D'oh just saw you don't want to use arcpy.GetInstallInfo()['InstallDir']

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

you can cheat... a demo using spyder as the python ide

import sys
src = [i for i in sys.path if 'spyder' in i]

Then it gives you the source for Pro since the distribution of spyder is buried within... do the split, join thing or just read it.  Works with any ide installed within your conda distribution (ie pythonwin, if installed that way)

Too lazy to figure out registry stuff.  But you probably don't have the luxury of local installs I bet

JoshuaBixby
MVP Esteemed Contributor

If I run your code, or equivalent code, from Pro Python installation; it works fine.  I think the issue is that you are using a 32-bit Python interpreter to access the 64-bit space in the registry.  The following should point you in the right direction:  Change 64bit Registry from 32bit Python - Stack Overflow 

GünterDörffel
Occasional Contributor III

Support for Joshua - and there's others who had that issue with 32bit: Python winreg looping through sub-keys - Stack Overflow 

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

Here is another cool one from the depths of esri's own code

import os
import sys
d = os.path.abspath(os.path.join(sys.prefix, '..', '..', '..'))
#
# Which returns .... 'C:\\ArcPro\\bin' .... where I installed my ArcGIS PRO
‍‍‍‍‍‍‍‍‍‍‍

but again, that has to be done with an IDE controlled by the conda distribution (Spyder in my case)

And from ...Jupyter QtConsole... so at least two IDEs bundled by esri for working with ArcGIS Pro can find it, as would be expected

Now if you are using python 3, _winreg is now winreg and this also works for my installation

import winreg

with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
...                      r"SOFTWARE\ESRI\ArcGISPro") as key:
                         pro_path = winreg.QueryValueEx(key, "InstallDir")[0]
                         

pro_path
Out[4]: 'C:\\ArcPro\\'
0 Kudos
curtvprice
MVP Esteemed Contributor

Read the fine manual, right Joshua?

35.3. _winreg — Windows registry access — Python 2.7.13 documentation 

Accessing an Alternate Registry View (Windows) 

import _winreg
with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
                     r"SOFTWARE\ESRI\ArcGISPro",
                     0,
                     _winreg.KEY_READ | _winreg.KEY_WOW64_64KEY
                     ) as key:
    pro_path = _winreg.QueryValueEx(key, "InstallDir")[0]

print(pro_path)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

This prints:

C:\ArcGIS\Pro\

Here's a little esoterica about these flags used in line 5. These are integer flags, combined above with "|" which does a bitwise or operation. (Adding the integers would work just as well.) The idea of the integer flags is they allow the developers to cram multiple boolean flags in one integer value since the bit locations are set up to be different for each flag. This makes more sense when you look at the numbers in hex. Imagine a function that has many flags to control what it does. This technique allows you to cram as many as 32 values into a single 32-bit integer, simplifying your argument call dramatically.

I needed both of these flags to get my function to work: KEY_WOW_64KEY forces a 64-bit 'view' of the registry so my 32-bit app can read 64-bit keys, and KEY_READ makes sure I open the registry read-only (this avoid access errors).

>>> flags = [_winreg.KEY_READ, _winreg.KEY_WOW64_64KEY]
>>> flags.append(flags[0] | flags[1]) # bitwise OR
>>> flags
[131097, 256, 131353]
>>> ["0x{:08x}".format(f) for f in flags] # print in hex
['0x00020019', '0x00000100', '0x00020119']‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍