Pracuję z dodatkiem ArcMap w C #. Z kodu C # wykonałem kilka skryptów Python. Teraz, aby uruchomić ten skrypt, mam zakodowaną ścieżkę do Pythona. Ale to nie jest przenośne. Tak więc chcę uzyskać ścieżkę do pliku wykonywalnego Python z kodu i użyć go.
Pytanie:
Jak mogę uzyskać ścieżkę do pliku wykonywalnego Pythona używanego przez ArcMap z kodu C #?
EDYTOWAĆ :
Z twoich sugestii na razie używam „środowiska ścieżek”, aby uzyskać ścieżkę do Pythona.
//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;
}
}
}
Ale jest problem:
Kiedy na moim komputerze jest zainstalowana inna wersja Pythona, nie ma gwarancji, że używam „python.exe”, ArcGIS również tego używa.
Nie doceniam używania innego narzędzia do uzyskania ścieżki „python.exe” . Naprawdę myślę, czy jest jakiś sposób na uzyskanie ścieżki z klucza rejestru. Dla „ArcGIS10.0” wygląd rejestru takich jak:
W tym celu myślę o następującym sposobie zdobycia ścieżki:
//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 ;
}
Ale przed skorzystaniem z drugiej procedury muszę się upewnić co do moich domysłów. Domysłami są:
- „Prawda” powiązana z pythonem oznacza, że Python jest instalowany z ArcGIS
- ArcGIS 10.0 i klucz rejestru wyższej wersji zostaną zapisane w tym samym procesie.
Proszę o pomoc w uzyskaniu wyjaśnień na temat moich domysłów.
źródło
Odpowiedzi:
Wziąłem twój drugi przykład kodu, sprawiłem, że działa zarówno na 64-bitowym, jak i 32-bitowym systemie operacyjnym, i trochę go uprościłem. Działa dla mnie w wersji 10.1 na Windows 7 64-bit, ale oczywiście powinieneś przetestować go na tak wielu środowiskach, jak to możliwe, i dodać ponownie wszelkie kontrole programowania obronnego, które uważasz za konieczne.
Po przetestowaniu czystej instalacji ArcGIS Desktop 10.1 bez Pythona stwierdziłem, że nie zawiera on podklucza Python10.x, nie mówiąc już o wartości True / False „Python” (wciąż nie jestem pewien, do czego to służy, w razie potrzeby skontaktuj się z obsługą ESRI wiedzieć).
Na komputerze stacjonarnym 10.1 z Pythonem funkcja ta powraca
C:\Python27\ArcGIS10.1\python.exe
. Na komputerze stacjonarnym 10.1 bez Pythona powoduje to wyjątek InvalidOperationException ze względu na brak klucza Python10.x.Mam nadzieję, że to pomoże ci w tym, co naprawdę próbujesz osiągnąć, co - o dziwo - wciąż nie jest dla mnie jasne.
źródło
Zamiast szukać pliku wykonywalnego w języku Python, ten temat pomocy sugeruje
cmd.exe
uruchomienie i uruchomieniepython.exe
bez określania jego lokalizacji. Należy jednak pamiętać, żepowinnotodziałać, ponieważ konfigurator instalatora ArcGIS Desktop(edycja: ostatnio przetestowana w wersji 10.1, nie działa) zależy od ścieżkipython.exe
dodawania doPATH
zmiennej środowiskowej użytkownika .Innym podejściem jest utworzenie narzędzia skryptowego i uruchomienie go z ArcObjects .
Jeśli naprawdę
python.exe
podążasz ścieżką do wersji ArcGIS , rozszerzając podejście narzędzia skryptowego ArcObjects +, możesz utworzyć narzędzie skryptowe Python, którego jedyną wartością wyjściową jest wartośćsys.exec_prefix
. Jest to ścieżka do folderu zawierającego wersję Pythona ArcGIS, npC:\Python27\ArcGIS10.1
.Uwaga dodatkowa :
sys.executable
zwraca ścieżkę doArcMap.exe
i NIEpython.exe
podczas uruchamiania w trakcie, dlatego nie sugeruję używania tej zmiennej.Wywołaj narzędzie skryptowe z ArcObjects i uzyskaj dane wyjściowe ze zwróconego
IGeoProcessorResult
obiektu.Aktualizacja: Oto przykładowy projekt dodatku ArcMap (VS2010, .NET 3.5), który używa narzędzia skryptowego spakowanego w dodatku, który po prostu wyświetla ścieżkę do
python.exe
używanego przez ArcMap: http://wfurl.com/cbd5091To tylko kliknięty przycisk i wyskakuje okno komunikatu ze ścieżką:
Ciekawe fragmenty kodu:
Skrypt w języku Python:
Funkcja C #:
źródło
PATH
zmiennej środowiskowej.Czy będziesz miał dostęp do rejestru?
Podczas instalacji ArcMap zainstaluje Python, jeśli nie będzie w stanie go znaleźć. Sprawdza w rejestrze, czy Python jest już zainstalowany. Uważam, że standardową lokalizacją rejestru dla tego jest: komputer \ HKEY_LOCAL_MACHINE \ SOFTWARE \ PYTHON \ PythonCore \ 2.7 \ InstallPath Z domyślną lokalizacją klucza ścieżki (2.7 to 10.1, 2.6 to 10.0)
Nie mogę wymyślić powodu, dla którego / dlaczego wartość tego klucza byłaby niepoprawna, ale zawsze możesz pójść w ten sposób: Wewnątrz rejestru Esri \ Desktop rejestru znajduje się lokalizacja w języku Python. Jest to prosta ścieżka, którą można uzyskać, a następnie zbudować dalsze ścieżki, aby upewnić się, że istnieje plik Python.exe. Na przykład klucz na komputerze 64-bitowym zostanie zainstalowany na: komputerze \ HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ ESRI \ Python10.1 Z kluczem PythonDir i powiązaną wartością ścieżki
Ale podoba mi się odpowiedź @ blah238. Po prostu otwórz monit w swoim programie i uruchom go tam. Nie widzę powodu, dla którego to nie działałoby.
źródło
[Edytuj] Wykonując
set
programowo (wykreślone poniżej) zrobiłem to, co chciałem, można to zrobić łatwiej i przy pomocy czystszego kodu za pomocą Environment.GetEnvironmentVariables () .Jedną z opcji byłoby skanowanie każdej zmiennej środowiskowej w systemie i próba udowodnienia, co następuje:
1) Czy wartość zmiennej środowiskowej jest katalogiem? (a jeśli tak..)
2) Czy ten katalog zawiera
python.exe
?Udało mi się to zrobić programowo, wykonującset
polecenie za pośrednictwem interfejsu API procesu .Net .set
Polecenia, jeżeli jest stosowany bez parametru, zwraca wszystkie zmienne środowiskowe używane przez system. Mogłem więc sparować, a następnie uporządkować emitowane wyniki STDOUTset
i przejrzeć je, aby zobaczyć, czy coś (i mam na myśli WSZYSTKO ) dostępne w środowisku systemowym ostatecznie wskazujepython.exe
.Z tej strony omawiającej
set
polecenie:Aby to zilustrować, napisałem kombinację metod (i klasy pomocniczej ), która robi to, co omówiłem powyżej. Można je zoptymalizować i mogą one użyć niektórych kuloodpornych (Try..Catch itp.), Ale jeśli komputer ma DOWOLNĄ zmienną środowiskową wskazującą na
python.exe
to, to podejście powinno ją znaleźć! Nie obchodzi mnie, czy var jest wywoływanyPATH
,ABBRACADABBRA
czy cokolwiek ... jeśli to wskazujepython.exe
, to powinno go znaleźć.Oto
terms
tablica ciągów, które przekazujesz do procedury w poszukiwaniu nazwy zmiennej środowiskowej lub jejn
wartości (tzn.PATH
Może mieć kilka wartości, ale większość innych zmiennych będzie miała tylko jedną). Upewnij się, że wszystkie napisyterms
są DUŻE!(Kiedy to przetestowałem, użyłem po prostu „PYTHON”, który znalazłem
C:\Python27\python.exe
w moim systemie domowym. Ale możesz z łatwością rozszerzyć go o kolejny ciąg [] terminów, jeśli chcesz dalej sprawdzić ścieżkępython.exe
zwróconych kandydatów --- dla przykład, aby sprawdzić, czy znajdują się w koszu ArcGIS itp.)Na dole mojej głównej klasy umieściłem następującą klasę pomocnika :
źródło
PYTHONPATH
zmienna NIE jest tą, którą chcesz.PATH
.PYTHONPATH
, że akurat był to jedyny war w tym konkretnym systemie, który wskazuje z powrotempython.exe
.) W każdym razie przerobiłem moją odpowiedź, aby zawierała działający przykład kodu C # i byłbym wdzięczny wiedząc, czy nadal nie zgadzasz się z tym podejściem. Dzięki / E.Chciałbym zaproponować alternatywne rozwiązanie w oparciu o mój komentarz w powyższym pytaniu. W przypadku bieżącego projektu robię coś bardzo podobnego; Mam dodatek .NET, który gdy użytkownik kliknie przycisk w interfejsie ArcMap, uruchamia skrypt w języku Python. Wymagałem, aby zmienna środowiskowa PATH ustawiona na plik wykonywalny ArcGIS Python była wymogiem, dzięki czemu nie muszę się martwić o włączenie ścieżki do pliku exe Python w moim kodzie .NET.
Teraz, podczas opracowywania, testerzy po prostu konfigurują zmienną PATH ręcznie. Ale w końcu utworzę instalator Windows (exe), który zainstaluje dodatek, zainstaluje dowolne zależności Pythona i ustawi wszelkie potrzebne zmienne PATH. W tym celu korzystam z Nullsoft Scriptable Install System (NSIS) , systemu open source do tworzenia instalatorów Windows. Oto kod, który opracowałem do tej pory, co jest dość szorstkie. Zasadniczo sprawdza w rejestrze, czy interesujące są zmienne PATH, a jeśli nie są, dodaje je. Oczywiście musi być uruchamiany jako administrator.
Zatem znowu nie znajduje to ścieżki do exe ArcGIS Python, ale pozwala dać użytkownikowi końcowemu moc, aby ustawić go poprawnie i łatwo.
źródło