Estou trabalhando com um suplemento do ArcMap em c #. No código C #, eu executei alguns scripts Python. Agora, para executar esses scripts, tenho um caminho python codificado. Mas isso não é portátil. Então, eu quero pegar o caminho do executável Python a partir do código e usá-lo.
Questão:
Como posso obter o caminho do executável Python usado pelo ArcMap a partir do código C #?
EDIT:
De suas sugestões, por enquanto estou usando o "caminho do ambiente" para obter o caminho do 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;
}
}
}
Mas há um problema:
Quando uma versão diferente do python é instalada na minha máquina, não há garantia de que o "python.exe" que estou usando, o ArcGIS também o utilize.
Não gosto de usar outra ferramenta para obter o caminho "python.exe" . Então, eu realmente acho que se existe alguma maneira de obter o caminho da chave do Registro. Para o registro "ArcGIS10.0", é semelhante a:
E para isso, estou pensando em seguir o caminho para seguir o caminho:
//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 ;
}
Mas antes de usar o segundo procedimento, preciso ter certeza sobre meus palpites. As suposições são:
- o "True" associado ao python significa que o python está instalado com o ArcGIS
- O ArcGIS 10.0 e a chave de registro da versão superior serão gravadas no mesmo processo.
Por favor, ajude-me a obter esclarecimentos sobre minhas suposições.
fonte
Respostas:
Peguei seu segundo exemplo de código, fiz funcionar em sistemas operacionais de 64 e 32 bits e simplifiquei um pouco. Funciona para mim na versão 10.1 no Windows 7 de 64 bits, mas obviamente você deve testá-lo no maior número possível de ambientes e adicionar novamente as verificações de programação defensiva que achar necessárias.
Após testar a instalação limpa do ArcGIS Desktop 10.1 sem Python, descobri que ela não inclui a subchave Python10.x, muito menos o valor True / False "Python" (ainda não sabe ao certo o que é isso, talvez entre em contato com o suporte da ESRI, se necessário) conhecer).
Em uma máquina Desktop 10.1 com Python, isso retorna
C:\Python27\ArcGIS10.1\python.exe
. Em uma máquina Desktop 10.1 sem Python, isso gera uma InvalidOperationException porque a chave Python10.x não está presente.Espero que isso ajude você com o que você está tentando realizar, o que - surpreendentemente - ainda não está claro para mim.
fonte
Em vez de procurar o executável Python, este tópico da ajuda sugere descascar
cmd.exe
e executarpython.exe
sem qualificar sua localização. Observe, no entanto, que issodeve funcionar porque o instalador do ArcGIS Desktop configura(editar: recentemente testado em 10.1, não) depende do caminho parapython.exe
ser adicionado àPATH
variável de ambiente do usuário .Outra abordagem é criar uma ferramenta de script e executá-la no ArcObjects .
Se você realmente está atrás do caminho para a versão do ArcGIS
python.exe
, por extensão da abordagem da ferramenta de script ArcObjects +, pode criar uma ferramenta de script Python cuja única saída é o valor desys.exec_prefix
. Este é o caminho da pasta que contém a versão do Python do ArcGIS, por exemploC:\Python27\ArcGIS10.1
.Nota lateral :
sys.executable
retorna o caminho paraArcMap.exe
e NÃOpython.exe
quando executado em processo, razão pela qual não sugiro o uso dessa variável.Chame a ferramenta de script do ArcObjects e obtenha a saída do
IGeoProcessorResult
objeto retornado .Atualização: Aqui está um exemplo de projeto de complemento do ArcMap (VS2010, .NET 3.5) que usa uma ferramenta de script empacotada no suplemento que simplesmente exibe o caminho para o
python.exe
usado pelo ArcMap: http://wfurl.com/cbd5091É apenas um botão no qual você clica e aparece uma caixa de mensagens com o caminho:
Os bits interessantes do código:
Script Python:
Função C #:
fonte
PATH
variável de ambiente.Você terá acesso ao registro?
Ao instalar o ArcMap, ele instalará o Python, se não conseguir encontrá-lo. Ele procura no registro para ver se o Python já está instalado. Acredito que o local padrão do registro para isso seja: computer \ HKEY_LOCAL_MACHINE \ SOFTWARE \ PYTHON \ PythonCore \ 2.7 \ InstallPath Com uma chave padrão do local do caminho (2.7 sendo 10.1, 2.6 sendo 10.0)
Não consigo pensar em uma razão pela qual / por que o valor dessa chave esteja incorreto, mas você sempre pode seguir este caminho: Dentro da seção Esri \ Desktop do registro há um local em Python. É o caminho simples que você pode obter e criar outros caminhos para garantir a existência de um Python.exe. Por exemplo, a chave em uma máquina de 64 bits é instalada em: computer \ HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ ESRI \ Python10.1 Com uma chave PythonDir e o valor associado do caminho
Mas eu gosto da resposta @ blah238. Basta abrir um prompt do seu programa e executá-lo lá. Não vejo uma razão para que isso não funcione.
fonte
[Editar] Ao executar
set
programaticamente (destacado abaixo) o que eu queria, ele pode ser realizado mais facilmente e com um código mais limpo usando Environment.GetEnvironmentVariables () .Uma opção seria verificar todas as variáveis de ambiente no sistema e tentar provar o seguinte:
1) O valor da variável de ambiente é um diretório? (e se..)
2) Esse diretório contém
python.exe
?Consegui fazer isso programaticamente executando oset
comando por meio da .Net Process API . Oset
comando, quando usado sem um parâmetro, retorna TODAS as variáveis de ambiente em uso pelo sistema. Para que eu pudesse fazer uma parada, organizar os resultados STDOUT emitidosset
e examiná- los para ver se havia alguma coisa disponível (e eu quero dizer QUALQUER COISA ) disponível através do ambiente do sistemapython.exe
.A partir desta página discutindo o
set
comando:Para ilustrar, escrevi uma combinação de métodos (e uma classe auxiliar ) que faz o que discuti acima. Eles podem ser otimizados e podem ser utilizados como prova de balas (Try..Catch, etc.), mas se o computador tiver QUALQUER variável de ambiente apontando
python.exe
, essa abordagem deve ser encontrada! Eu não me importo se o var é chamadoPATH
,ABBRACADABBRA
ou o que seja .. se ele apontapython.exe
, isso deve ser encontrado.Aqui
terms
está uma matriz de strings que você transmite à rotina para procurar no nome da variável de ambiente ou em seusn
valores (ou seja,PATH
pode ter vários valores, mas a maioria dos outros vars terá apenas um). Verifique se todas as stringsterms
estão em MAIÚSCULAS!(Quando testei isso, usei simplesmente "PYTHON", encontrado
C:\Python27\python.exe
no meu sistema doméstico. Mas você pode estendê-lo facilmente para incluir outra sequência de termos [] se quiser inspecionar melhor o caminho de qualquerpython.exe
candidato retornado --- para exemplo, para ver se eles estavam na bandeja do ArcGIS, etc.)E na parte inferior da minha classe principal, incluí a seguinte classe auxiliar :
fonte
PYTHONPATH
variável NÃO é a que você deseja.PATH
.PYTHONPATH
, que era a única var nesse sistema específico que aponta para tráspython.exe
.) De qualquer forma, revisei minha resposta para incluir um exemplo de código C # funcional e agradeceria saber se você ainda não concorda com essa abordagem. Obrigado / E.Gostaria de oferecer uma solução alternativa, com base no meu comentário na pergunta acima. Para um projeto atual, estou fazendo algo muito semelhante; Eu tenho um suplemento .NET que, quando o usuário clica em um botão na interface do ArcMap, um script Python é executado. Eu fiz com que uma variável de ambiente PATH definida como executável do ArcGIS Python fosse um requisito, para que eu realmente não tenha que me preocupar em incluir o caminho para o exe do Python no meu código .NET.
Agora, enquanto em desenvolvimento, os testadores estão apenas configurando a variável PATH manualmente. Mas, eventualmente, terei um instalador do Windows (exe) criado que instalará o suplemento, instalará quaisquer dependências do Python e definirá as variáveis PATH necessárias. Para isso, estou usando o NSIS (Nullsoft Scriptable Install System) , um sistema de código aberto para a criação de instaladores do Windows. Aqui estão alguns dos códigos que desenvolvi até agora, o que é bastante difícil. Basicamente, ele procura no registro para ver se as variáveis PATH de interesse estão lá e, se não estiverem, as adiciona. Tem que ser executado como administrador, é claro.
Portanto, novamente, isso não encontra o caminho para o ArcGIS Python exe, mas permite que você dê ao usuário final o poder de configurá-lo de maneira adequada e fácil.
fonte