Я работаю с надстройкой ArcMap в C #. Из кода C # я выполнил несколько скриптов Python. Теперь, чтобы запустить этот скрипт, у меня есть жестко запрограммированный путь к Python. Но это не портативно. Итак, я хочу получить путь к исполняемому файлу Python из кода и использовать его.
Вопрос:
Как я могу получить путь к исполняемому файлу Python, используемому ArcMap, из кода C #?
РЕДАКТИРОВАТЬ :
Из ваших предложений, сейчас я использую "путь среды", чтобы получить путь Python.
//get python path from environtment variable
string GetPythonPath()
{
IDictionary environmentVariables = Environment.GetEnvironmentVariables();
string pathVariable = environmentVariables["Path"] as string;
if (pathVariable != null)
{
string[] allPaths = pathVariable.Split(';');
foreach (var path in allPaths)
{
string pythonPathFromEnv = path + "\\python.exe";
if (File.Exists(pythonPathFromEnv))
return pythonPathFromEnv;
}
}
}
Но существует проблема:
Когда на моей машине установлена другая версия python, нет никакой гарантии, что «python.exe», который я использую, ArcGIS также использует.
Я не ценю использование другого инструмента для получения пути "python.exe" . Итак, я действительно думаю, есть ли способ получить путь из раздела реестра. Для «ArcGIS10.0» реестр выглядит так:
И для этого я думаю о следующем пути, чтобы получить путь:
//get python path from registry key
string GetPythonPath()
{
const string regKey = "Python";
string pythonPath = null;
try
{
RegistryKey registryKey = Registry.LocalMachine;
RegistryKey subKey = registryKey.OpenSubKey("SOFTWARE");
if (subKey == null)
return null;
RegistryKey esriKey = subKey.OpenSubKey("ESRI");
if (esriKey == null)
return null;
string[] subkeyNames = esriKey.GetSubKeyNames();//get all keys under "ESRI" key
int index = -1;
/*"Python" key contains arcgis version no in its name. So, the key name may be
varied version to version. For ArcGIS10.0, key name is: "Python10.0". So, from
here I can get ArcGIS version also*/
for (int i = 0; i < subkeyNames.Length; i++)
{
if (subkeyNames[i].Contains("Python"))
{
index = i;
break;
}
}
if(index < 0)
return null;
RegistryKey pythonKey = esriKey.OpenSubKey(subkeyNames[index]);
string arcgisVersion = subkeyNames[index].Remove(0, 6); //remove "python" and get the version
var pythonValue = pythonKey.GetValue("Python") as string;
if (pythonValue != "True")//I guessed the true value for python says python is installed with ArcGIS.
return;
var pythonDirectory = pythonKey.GetValue("PythonDir") as string;
if (pythonDirectory != null && Directory.Exists(pythonDirectory))
{
string pythonPathFromReg = pythonDirectory + "ArcGIS" + arcgisVersion + "\\python.exe";
if (File.Exists(pythonPathFromReg))
pythonPath = pythonPathFromReg;
}
}
catch (Exception e)
{
MessageBox.Show(e + "\r\nReading registry " + regKey.ToUpper());
pythonPath = null;
}
return pythonPath ;
}
Но прежде чем использовать вторую процедуру, я должен быть уверен в своих догадках. Предположения:
- «True», связанный с python, означает, что python установлен с ArcGIS
- Ключ реестра ArcGIS 10.0 и более поздней версии будет записан в одном процессе.
Пожалуйста, помогите мне получить какие-либо разъяснения о моих догадках.
источник
Ответы:
Я взял ваш второй пример кода, заставил его работать как на 64, так и на 32-битных ОС и немного упростил его. У меня работает в версии 10.1 на 64-битной Windows 7, но, очевидно, вы должны протестировать его в максимально возможном количестве сред и добавить обратно в любые проверки защитного программирования, которые вы считаете необходимыми.
После тестирования чистой установки ArcGIS Desktop 10.1 без Python я обнаружил, что он не включает подраздел Python10.x, не говоря уже о значении True / False "Python" (все еще не уверен, для чего оно, возможно, обратитесь в службу поддержки ESRI, если необходимо знаю).
На компьютере с Desktop 10.1 с Python это возвращается
C:\Python27\ArcGIS10.1\python.exe
. На компьютере Desktop 10.1 без Python это вызывает исключение InvalidOperationException из-за отсутствия ключа Python10.x.Надеюсь, это поможет вам с тем, что вы пытаетесь достичь на самом деле, что - удивительно - до сих пор не ясно для меня.
источник
Вместо того, чтобы искать исполняемый файл Python, этот раздел справки предлагает обстреливать
cmd.exe
и запускатьpython.exe
без указания его местоположения. Однако обратите внимание, что этодолжно работать, потому что установщик ArcGIS Desktop устанавливает(редактировать: недавно протестировано в 10.1, это не так) зависит от пути кpython.exe
добавлению вPATH
переменную окружения пользователя .Другой подход - создать инструмент-скрипт и запустить его из ArcObjects .
Если вы действительно
python.exe
следуете пути к версии ArcGIS , с помощью расширения инструмента-скрипта ArcObjects + вы можете создать инструмент-скрипт Python, единственным выходным значением которого является значениеsys.exec_prefix
. Это путь к папке, содержащей версию Python ArcGIS, напримерC:\Python27\ArcGIS10.1
.Примечание :
sys.executable
возвращает путь кArcMap.exe
и НЕpython.exe
при запуске в процессе, поэтому я не предлагаю использовать эту переменную.Вызвать инструмент-скрипт из ArcObjects и получить выходные данные возвращаемого
IGeoProcessorResult
объекта.Обновление: вот пример проекта надстройки ArcMap (VS2010, .NET 3.5), в котором используется инструмент-скрипт, упакованный в надстройке, который просто отображает путь к
python.exe
используемому ArcMap: http://wfurl.com/cbd5091Это просто кнопка, которую вы нажимаете, и появляется окно сообщения с путем:
Интересные фрагменты кода:
Скрипт Python:
Функция C #:
источник
PATH
переменной среды.Будет ли у вас доступ к реестру?
При установке ArcMap он установит Python, если не сможет его найти. Он просматривает реестр, чтобы увидеть, установлен ли Python. Я считаю, что стандартное расположение реестра для этого: computer \ HKEY_LOCAL_MACHINE \ SOFTWARE \ PYTHON \ PythonCore \ 2.7 \ InstallPath со стандартным ключом расположения пути (2.7 - 10.1, 2.6 - 10.0)
Я не могу придумать причину, когда / почему значение этого ключа будет неправильным, но вы всегда можете пойти по этому пути: внутри куста Esri \ Desktop реестра находится расположение Python. Это простой путь, который вы можете получить, а затем создать дополнительные пути, чтобы обеспечить наличие Python.exe. Например, ключ на 64-битной машине устанавливается на: computer \ HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ ESRI \ Python10.1 с ключом PythonDir и соответствующим значением Path
Но мне нравится ответ @ blah238. Просто откройте подсказку из вашей программы и запустите ее там. Я не вижу причины, по которой это не сработает.
источник
[Редактировать] Хотя
set
программное выполнение (вычеркнуто ниже) сделало то, что я хотел, это можно сделать проще и с помощью более чистого кода с помощью Environment.GetEnvironmentVariables () .Одним из вариантов будет сканирование каждой переменной среды в системе и попытка доказать следующее:
1) Является ли значение переменной среды каталогом? (и если это так..)
2) Содержит ли этот каталог
python.exe
?Я смог сделать это программно, выполнивset
команду через .Net Process API . Командаset
, если она используется без параметра, возвращает ВСЕ переменные среды, используемые системой. Таким образом, я мог бы проанализировать, затем упорядочить результаты STDOUT, полученные изset
, и просмотреть их, чтобы увидеть, на что в конечном итоге указывалось что-либо (и я имею в виду НИЧЕГО ), доступное через системуpython.exe
.С этой страницы обсуждаем
set
команду:Чтобы проиллюстрировать это, я написал комбинацию методов (и вспомогательный класс ), которые делают то, что я обсуждал выше. Они могут быть оптимизированы, и они могут использовать некоторые пуленепробиваемые (Try..Catch и т. Д.), Но если на компьютере есть ЛЮБАЯ переменная среды, указывающая на
python.exe
, этот подход должен найти его! Меня не волнует , если переменная называетсяPATH
,ABBRACADABBRA
или любой .. если он указывает наpython.exe
это должно найти его.Вот
terms
массив строк, которые вы передаете в подпрограмму для поиска в имени переменной среды или в ееn
значениях (т.PATH
Е. Может иметь несколько значений, но большинство других переменных будет иметь только одно). Убедитесь, что все строки вterms
верхнем регистре!(Когда я проверял это, я использовал просто «PYTHON», который был найден
C:\Python27\python.exe
в моей домашней системе. Но вы могли бы легко расширить его, добавив еще одну строку [] терминов, если вы хотите дополнительно проверить путь любыхpython.exe
возвращаемых кандидатов - для например, чтобы увидеть, были ли они в бункере ArcGIS и т. д.)И в нижней части моего основного класса я включил следующий класс помощника :
источник
PYTHONPATH
переменная НЕ та, которую вы хотите.PATH
.PYTHONPATH
, что это единственная переменная в этой конкретной системе, указывающая на этоpython.exe
.) В любом случае, я пересмотрел свой ответ, включив в него работающий пример кода C #, и я был бы признателен зная, если вы все еще не согласны с этим подходом. Спасибо / E.Я хотел бы предложить альтернативное решение, основываясь на моем комментарии в вопросе выше. Для текущего проекта я делаю нечто очень похожее; У меня есть надстройка .NET, которая, когда пользователь нажимает кнопку в пользовательском интерфейсе ArcMap, запускает скрипт Python. Я сделал требование иметь переменную среды PATH, установленную на исполняемый файл ArcGIS Python, таким образом, мне не нужно беспокоиться о включении пути к файлу Python в мой код .NET.
Сейчас, в процессе разработки, тестеры просто настраивают переменную PATH вручную. Но со временем у меня будет создан установщик Windows (exe), который установит надстройку, установит все зависимости Python и установит все необходимые переменные PATH. Для этого я использую Nullsoft Scriptable Install System (NSIS) , систему с открытым исходным кодом для создания установщиков Windows. Вот некоторый код, который я разработал до сих пор, который довольно грубый. По сути, он просматривает реестр, чтобы увидеть, есть ли переменные PATH, представляющие интерес, и если нет, то добавляет их. Конечно, должен быть запущен от имени администратора.
Итак, опять же, это не находит путь к ArcGIS Python exe, но позволяет вам дать конечному пользователю возможность установить его правильно и легко.
источник