Wie kann ich den von ArcMap verwendeten Pfad von "Python.exe" programmgesteuert ermitteln?

15

Ich arbeite mit einem Add-In von ArcMap in C #. Aus C # -Code habe ich einige Python-Skripte ausgeführt. Um dieses Skript auszuführen, habe ich den Python-Pfad fest programmiert. Dies ist jedoch nicht portabel. Daher möchte ich den Pfad der ausführbaren Python-Datei aus dem Code abrufen und verwenden.

Frage:

Wie kann ich den Pfad der von ArcMap verwendeten ausführbaren Python-Datei aus C # -Code abrufen?

EDIT:

Nach Ihren Vorschlägen verwende ich jetzt "Pfadumgebung", um Python-Pfad zu erhalten.

//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;
        }
    }
}

Aber es gibt ein Problem:

Wenn auf meinem Computer eine andere Version von Python installiert ist, kann nicht garantiert werden, dass die von mir verwendete "python.exe" auch von ArcGIS verwendet wird.

Ich schätze es nicht, ein anderes Tool zu verwenden, um den Pfad "python.exe" abzurufen . Also, ich denke wirklich, ob es eine Möglichkeit gibt, den Pfad vom Registrierungsschlüssel abzurufen. Die Registrierung für "ArcGIS10.0" sieht folgendermaßen aus: Bildbeschreibung hier eingeben

Und dafür denke ich über folgenden Weg nach, um den Weg zu finden:

//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 ;
}

Aber bevor ich das zweite Verfahren verwende, muss ich mir sicher sein, was meine Vermutungen sind. Vermutungen sind:

  1. "True" in Verbindung mit Python bedeutet, dass Python mit ArcGIS installiert wird
  2. ArcGIS 10.0 und der Registrierungsschlüssel der höheren Version werden in demselben Prozess geschrieben.

Bitte helfen Sie mir, meine Vermutungen zu klären.

Emi
quelle
5
Haben Sie darüber nachgedacht, ein Skript-Tool zu erstellen und in ArcObjects auszuführen ?
blah238
3
Können Sie nicht einfach eine PATH-Umgebungsvariable auf ArcGIS Python setzen, um eine Installationsanforderung für Ihr Add-In zu erhalten?
Chad Cooper
Alles in allem muss @ChadCoopers Gedanke der beste Weg sein. Anstatt zu versuchen, rückwärts zu arbeiten, stellen Sie dies bei der Installation ein für alle Mal ein.
Elrobis
@ elrobis: Ich weiß, der Pfad in der PATH-Umgebung ist ein guter Weg. Aber ich wollte wissen, ob es eine Möglichkeit gibt, die Python zu finden und alles zu tun, ohne den Benutzer zu unterbrechen.
Emi
@ blah238 danke für deinen vorschlag. Ich habe noch nie mit Script Tool gearbeitet. Vielleicht muss ich etwas darüber lernen
Emi

Antworten:

2

Ich nahm Ihr zweites Codebeispiel, ließ es auf 64- und 32-Bit-Betriebssystemen funktionieren und vereinfachte es ein wenig. Funktioniert für mich mit 10.1 unter Windows 7 64-Bit, aber Sie sollten es natürlich in so vielen Umgebungen wie möglich testen und bei den von Ihnen als notwendig erachteten defensiven Programmierüberprüfungen wieder hinzufügen.

Nach dem Testen der Neuinstallation von ArcGIS Desktop 10.1 ohne Python stellte ich fest, dass der Unterschlüssel Python10.x nicht enthalten ist, geschweige denn der Wert "Python" True / False kennt).

string GetPythonPath()
{
    string pythonPath = null;
    var localmachineKey = Registry.LocalMachine;
    // Check whether we are on a 64-bit OS by checking for the Wow6432Node key (32-bit version of the Software registry key)
    var softwareKey = localmachineKey.OpenSubKey(@"SOFTWARE\Wow6432Node"); // This is the correct key for 64-bit OS's
    if (softwareKey == null) {
        softwareKey = localmachineKey.OpenSubKey("SOFTWARE"); // This is the correct key for 32-bit OS's
    }
    var esriKey = softwareKey.OpenSubKey("ESRI");
    var realVersion = (string)esriKey.OpenSubKey("ArcGIS").GetValue("RealVersion"); // Get the "real", canonical version of ArcGIS
    var shortVersion = String.Join(".", realVersion.Split('.').Take(2).ToArray()); // Get just the Major.Minor part of the version number, e.g. 10.1
    var pythonKey = esriKey.OpenSubKey("Python" + shortVersion); // Open the Python10.x sub-key
    if (pythonKey == null) {
        throw new InvalidOperationException("Python not installed with ArcGIS!");
    }
    var pythonDirectory = (string)pythonKey.GetValue("PythonDir");
    if (Directory.Exists(pythonDirectory))
    {
        // Build path to python.exe
        string pythonPathFromReg = Path.Combine(Path.Combine(pythonDirectory, "ArcGIS" + shortVersion), "python.exe");
        if (File.Exists(pythonPathFromReg)) {
            pythonPath = pythonPathFromReg;
        }
    }
    return pythonPath;
}

Auf einem Desktop 10.1-Computer mit Python wird dies zurückgegeben C:\Python27\ArcGIS10.1\python.exe. Auf einem Desktop 10.1-Computer ohne Python wird eine InvalidOperationException ausgelöst, da der Schlüssel Python10.x nicht vorhanden ist.

Hoffentlich hilft dir das bei allem, was du tatsächlich erreichen willst, was mir - erstaunlicherweise - immer noch nicht klar ist.

blah238
quelle
7

Anstatt nach der ausführbaren Python-Datei zu suchen, wird in diesem Hilfethema vorgeschlagen, die Ausführung zu cmd.exebeenden, python.exeohne den Speicherort zu qualifizieren. Beachten Sie jedoch, dass dies funktionieren sollte , da das Einrichten des ArcGIS Desktop-Installationsprogramms (Bearbeiten: vor kurzem bei 10.1 getestet, nicht bei 10.1 getestet) davon abhängt, dass der Pfad zur Umgebungsvariablen python.exedes Benutzers hinzugefügt PATHwird.

Ein weiterer Ansatz ist es, einen erstellen Skript - Tool und es von ArcObjects ausführen .

Wenn Sie wirklich den Pfad zur ArcGIS-Version von python.exesuchen, können Sie in Erweiterung des ArcObjects + -Skripttool-Ansatzes ein Python-Skripttool erstellen, dessen einzige Ausgabe der Wert von ist sys.exec_prefix. Dies ist der Pfad des Ordners, der die ArcGIS-Version von Python enthält, z C:\Python27\ArcGIS10.1.

Randnotiz : sys.executableGibt den Pfad zu ArcMap.exeund NICHT zurück, python.exewenn sie in-process ausgeführt werden, weshalb ich nicht vorschlage, diese Variable zu verwenden.

Rufen Sie das Skriptwerkzeug in ArcObjects auf und rufen Sie die Ausgabe des zurückgegebenen IGeoProcessorResultObjekts ab.

Update: In diesem Beispielprojekt für ein ArcMap-Add-In (VS2010, .NET 3.5) wird ein im Add-In enthaltenes Skript-Tool verwendet, das einfach den Pfad zu dem python.exevon ArcMap verwendeten Pfad anzeigt: http://wfurl.com/cbd5091

Es ist nur eine Schaltfläche, auf die Sie klicken, und es wird ein Nachrichtenfenster mit dem folgenden Pfad angezeigt:

Taste Nachrichtenbox

Die interessanten Teile des Codes:

  • Python-Skript:

    import sys
    import os
    import arcpy
    
    def getPythonPath():
        pydir = sys.exec_prefix
        pyexe = os.path.join(pydir, "python.exe")
        if os.path.exists(pyexe):
            return pyexe
        else:
            raise RuntimeError("No python.exe found in {0}".format(pydir))
    
    if __name__ == "__main__":
        pyexe = getPythonPath()
        arcpy.AddMessage("Python Path: {0}".format(pyexe))
        arcpy.SetParameterAsText(0, pyexe)
  • C # -Funktion:

    public string GetPythonPath()
    {
        // Build the path to the PythonPathToolbox
        string toolboxPath = Path.Combine(Path.GetDirectoryName(this.GetType().Assembly.Location), "PythonPath.tbx");
    
        // Initialize the geoprocessor.
        IGeoProcessor2 gp = new ESRI.ArcGIS.Geoprocessing.GeoProcessorClass();
    
        // Add the PythonPath toolbox.
        gp.AddToolbox(toolboxPath);
    
        // Need an empty array even though we have no input parameters
        IVariantArray parameters = new VarArrayClass();
    
        // Execute the model tool by name.
        var result = gp.Execute("GetPythonPath", parameters, null);
        return result.GetOutput(0).GetAsText();
    }
blah238
quelle
2
In diesem Dokument heißt es jedoch nicht, dass das ArcGIS Desktop-Installationsprogramm den Pfad zu python.exe zur Umgebungsvariablen PATH des Benutzers einrichtet. Daher kann es sein, dass der Pfad von Python nicht in der Umgebungsvariablen PATH enthalten ist. Dann wird ein Fehler erzeugt. Wie kann ich also sicher sein, dass der ausführbare Pfad von Python in der Umgebungsvariablen PATH des Benutzers enthalten ist?
Emi
2
Sie können nicht, wie die meisten Dinge im Leben und im Rechnen, nur Annahmen treffen und hoffen, dass die Dinge funktionieren, und Sie können einen Fallback-Plan erstellen, wenn dies nicht der Fall ist (Anweisungen zum Hinzufügen zur Umgebungsvariablen PATH). Wenn es sich jedoch um eine normale Installation handelt, fügt das ArcGIS Desktop-Installationsprogramm diesen Pfad der Umgebungsvariablen PATH hinzu.
blah238
2
Ich habe viele Installationen gesehen, in denen sich das mit arcgis installierte Python nicht im Pfad befand. Und was ist, wenn zwei Versionen installiert sind und sich die "falsche" im Pfad befindet?
Blindjesse
In meinem dritten Absatz habe ich eine Lösung angeboten, mit der die ArcGIS-Installation von Python unabhängig von der PATHUmgebungsvariablen gefunden werden soll.
blah238
@ blah238 Macht das Erstellen eines Skript-Tools mein Add-In nicht weniger portabel oder erschwert es den Installationsprozess des Add-Ins für andere Computer?
Emi
6

Haben Sie Zugriff auf die Registrierung?

Bei der Installation von ArcMap wird Python installiert, wenn es nicht gefunden wird. In der Registrierung wird geprüft, ob Python bereits installiert ist. Ich glaube, der Standardspeicherort für die Registrierung ist: computer \ HKEY_LOCAL_MACHINE \ SOFTWARE \ PYTHON \ PythonCore \ 2.7 \ InstallPath Mit einem Standardschlüssel für den Pfadspeicherort (2.7 ist 10.1, 2.6 ist 10.0)

Ich kann mir keinen Grund vorstellen, wann / warum der Wert dieses Schlüssels falsch wäre, aber Sie könnten immer so vorgehen: In der Esri \ Desktop-Struktur der Registrierung befindet sich ein Python-Speicherort. Es ist der einfache Pfad, den Sie abrufen und dann weitere Pfade aufbauen können, um sicherzustellen, dass eine Python.exe vorhanden ist. Beispielsweise wird der Schlüssel auf einem 64-Bit-Computer installiert unter: computer \ HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \ ESRI \ Python10.1 Mit einem PythonDir-Schlüssel und einem zugeordneten Pfadwert

Aber ich mag @ blah238 Antwort. Öffnen Sie einfach eine Eingabeaufforderung in Ihrem Programm und führen Sie sie dort aus. Ich kann keinen Grund sehen, warum das nicht funktionieren würde.

KHibma
quelle
2
Dieser Ansatz ist auch fehlerhaft, da möglicherweise mehrere Python-Installationen vorhanden sind und Sie nicht auf einfache Weise programmgesteuert feststellen können, welche davon von ArcGIS verwendet wird. Wenn Sie nicht mit Arcpy arbeiten, ist dies jedoch möglicherweise nicht von Bedeutung. Dennoch denke ich, dass die robusteste Lösung die Registrierung und einiges an Logik beinhalten würde. Ich werde aber nicht dorthin gehen.
blah238
Nun, die Logik müsste mit der neuesten Version 2.7 beginnen und rückwärts arbeiten. Dies könnte natürlich fehlschlagen, wenn Sie eine neue Version von Python installiert und dann eine ältere Version von ArcGIS installiert haben, die eine ältere Version von Python installieren würde. Also ja, ich bin damit einverstanden, dass dieses Potenzial vorhanden ist, aber es ist unwahrscheinlich (oder Sie könnten einfach einen Lookup von arc10.1 = py2.7, arc10.0 = py26 ... usw. konstruieren, um 100% sicher zu sein). Wie gesagt, die beste Methode wäre wahrscheinlich, einfach die Eingabeaufforderung auszublenden.
KHibma
@ Khibma Ich suchte durch die Registrierung. Aber ich finde es wirklich lästig, wenn ich die "PYTHON" -Taste durchschaue. Auf meinem Computer sind zwei Python-Versionen installiert, und es werden beide zurückgegeben. Ich denke, es ist eine gute Idee, durch den "ESRI" -Schlüssel zu schauen, und wenn es einen "Python" -Schlüssel mit wahrem Wert gibt, dann kann ich den "PythonDir" -Schlüsselwert nehmen. Es funktioniert in meinem Fall :)
Emi
Ist dies ein falscher Weg, um den Python-Pfad in der Registrierung über den "ESRI" -Schlüssel zu durchsuchen? Oder gibt es eine Chance, dass die Art und Weise, wie esri verwendet, um Schlüssel und Werte in der Registrierung zu erstellen, geändert werden kann und der Code ihn möglicherweise nicht lesen kann
Emi
Wenn ich die Registrierung "durchsuchen" sage, verwende ich die tatsächlichen Pfade, die ich oben angegeben habe. Wenn jemand es nicht besser weiß, ändert sich der Speicherort dieser Registrierungsschlüssel (in der Registrierung) nicht von Computer zu Computer. So dass Sie nur die Pfade codieren würden , um zu sehen , ob existieren die Schlüssel da, wenn ja , was ist der Wert ...
KHibma
5

[Bearbeiten] Während die setprogrammgesteuerte Ausführung (siehe unten) das getan hat, was ich wollte, kann sie mit Environment.GetEnvironmentVariables () einfacher und mit saubererem Code ausgeführt werden .

Eine Möglichkeit wäre, jede Umgebungsvariable im System zu scannen und Folgendes zu beweisen:

1) Ist die Umgebungsvariable ein Verzeichnis? (und wenn..)

2) Enthält dieses Verzeichnis python.exe?

Ich konnte dies programmgesteuert tun, indem ich den setBefehl über die .NET- Prozess-API ausführte . Der setBefehl, wenn ohne Parameter verwendet wird , gibt alle Umgebungsvariablen in Verwendung durch das System. So konnte ich die von STDOUT ausgegebenen Ergebnisse parasieren, dann organisieren setund sie überprüfen, um festzustellen , ob in der Systemumgebung, auf die letztendlich verwiesen wurde, irgendetwas verfügbar ist (und ich meine ALLES ) python.exe.

Auf dieser Seite wird der setBefehl erläutert:

Geben Sie SET ohne Parameter ein, um alle aktuellen Umgebungsvariablen anzuzeigen.

Zur Veranschaulichung habe ich eine Kombination von Methoden (und eine Hilfsklasse ) geschrieben, die das tun, was ich oben besprochen habe. Diese können optimiert werden, und sie könnten eine Art Kugelsicherung (Try..Catch usw.) verwenden. Wenn der Computer jedoch auf eine beliebige Umgebungsvariable verweist, python.exesollte diese Methode sie finden! Es ist mir egal, ob der var aufgerufen PATHwird ABBRACADABBRAoder was auch immer. Wenn er darauf hinweist python.exe, sollte er gefunden werden.

// C#, you'll need these using statements:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;

Hier termsist ein Array von Zeichenfolgen, die Sie an die Routine übergeben, um entweder im Namen der Umgebungsvariablen oder in ihren nWerten zu suchen (dh sie PATHkönnen mehrere Werte haben, aber die meisten anderen Variablen haben nur einen). Stellen Sie sicher, dass alle Zeichenfolgen in termsGROSSBUCHSTABEN sind!

(Als ich das getestet habe, habe ich einfach "PYTHON" verwendet, das C:\Python27\python.exeauf meinem Heimsystem zu finden ist. Sie können es jedoch problemlos um eine weitere Zeichenfolge [] von Begriffen erweitern, wenn Sie den Pfad von zurückgegebenen python.exeKandidaten weiter untersuchen möchten B. um zu sehen, ob sie sich im ArcGIS-Bin befinden, usw.)

// Top-level method that organizes everything below..
private void scrapeEnvironmentVariables(string[] terms)
{
    // !! ValueObject !! This is a Helper Class, find it at the bottom..
    List<ValueObject> voList = buildListOfEnvironmentObjects();

    foreach (ValueObject vo in voList)
    {
        bool candidateFound = ObjectMatchesSearchTerms(vo, terms);

        if (candidateFound)
        {    
            string exeCandidate = "";
            foreach (string unlikelyPath in vo.values)
            {
                if (Directory.Exists(unlikelyPath))
                {
                    string unlikelyExe = unlikelyPath + "\\python.exe";
                    if(File.Exists(unlikelyExe))
                        exeCandidate = unlikelyExe;
                }

                if (exeCandidate != "")
                {
                    break;
                    // At this point, exeCandidate is a fully-qualified
                    // path to python.exe..
                }
            }

            // If you only want the first hit, break here..
            // As-is, the code will look for even more matches.
            //if (breakOnFirstHit)
            //    break;
        }
    }
}


// Execute Environment.GetEnvironmentVariables() and organize the 
// key..value pairs into 1:n ValueObjects (see Helper Class below).
private List<ValueObject> buildListOfEnvironmentObjects()
{
    // Return a List of 1:n key..value objects.
    List<ValueObject> voList = new List<ValueObject>();

    IDictionary variableDictionary = Environment.GetEnvironmentVariables();
    foreach (DictionaryEntry entry in variableDictionary)
    {
        // Explode multi-values into a List of values (n).
        List<string> values = new List<string>();
        string[] rawValues = ((string)entry.Value).Split(';');
        foreach (string value in rawValues)
            if (value != "") values.Add(value.ToUpper());

        ValueObject valueObject = new ValueObject();
        valueObject.key = ((string)entry.Key).ToUpper();
        valueObject.values = values.ToArray();

        voList.Add(valueObject);
    }
    return voList;
}


// Compare the key and any value(s) in a ValueObject with all the
// terms submitted to the top-level method. If **ALL** the terms
// match (against any combination of key..value), it returns true.
private bool ObjectMatchesSearchTerms(ValueObject vo, string[] terms)
{
    int matchCount = 0;

    foreach (string term in terms)
    {
        if (vo.key.Contains(term))              // screen the key
            matchCount++;

        foreach (string value in vo.values)     // screen N values
        {
            if (value.Contains(term))
                matchCount++;
        }
    }

    // Test against >= because it's possible the match count could
    // exceed the terms length, like if a match occurred in both the
    // key and the value(s). So >= avoids omiting that possibility.
    return (matchCount >= terms.Length) ? true : false;
}    

Und am Ende meiner Hauptklasse habe ich die folgende Helferklasse eingefügt :

class ValueObject : Object
{
    public ValueObject() { } // default constructor

    public string key;
    public string[] values;
}
Elrobis
quelle
1
Dies ist fragil, da der Benutzer das Python-Installationsverzeichnis im ArcGIS Desktop-Installationsprogramm anpassen kann. Auch die PYTHONPATHVariable ist NICHT die, die Sie wollen.
blah238
@ blah238, manchmal ist alles, was du hast, fragil. Ich war tatsächlich überrascht zu sehen, dass Arc gegen PYTHONPATH verkabelt war. Dies ist eine Standardinstallation von 9.2. Nichtsdestotrotz fragte das OP, wie programmgesteuert auf die ArcGIS-Datei python.exe zugegriffen werden soll, und der von mir empfohlene Ansatz, ob fragil oder nicht, tut dies.
Elrobis
Ich kann nicht sagen, dass ich die Abwärtsabstimmung verstehe. Ist diese Antwort wirklich " nicht nützlich "? Es ist vielleicht nicht so toll , aber es ist sicherlich eine Option, die wahrscheinlich für eine typische Arc-Installation funktioniert. Zumindest fügt es dem Thread etwas Nützliches hinzu - insbesondere zeigt es eine Standard-Arc-Installation, bei der das Verknüpfen des Pythons aktiviert ist. exe mit einer anderen Umgebungsvariablen als PATH.
Elrobis
Entschuldigung, aber Sie sind falsch. Die Variable PYTHONPATH wird von Python zum Suchen von Modulen verwendet, nicht von ArcGIS zum Suchen von Python. Überprüfen Sie den Link.
blah238
@ blah238, ich denke, der Screenshot hat den Punkt, den ich machen wollte, überwältigt / verdunkelt. (Insbesondere wollte mein Vorschlag an das OP nicht betonen PYTHONPATH, dass dies zufällig die einzige Variable auf diesem speziellen System war, auf die zurückgegriffen wurde python.exe.) Wie auch immer, ich habe meine Antwort überarbeitet, um ein funktionierendes C # -Codebeispiel aufzunehmen, und ich würde es begrüßen zu wissen, ob Sie mit diesem Ansatz noch nicht einverstanden sind. Danke / E.
Elrobis
4

Ich möchte eine alternative Lösung anbieten, basierend auf meinem Kommentar in der obigen Frage. Für ein aktuelles Projekt mache ich etwas sehr Ähnliches; Ich habe ein .NET-Add-In, das ein Python-Skript ausführt, wenn der Benutzer auf eine Schaltfläche in der ArcMap-Benutzeroberfläche klickt. Ich habe das Festlegen einer PATH-Umgebungsvariablen für die ausführbare ArcGIS-Python-Datei zu einer Anforderung gemacht. Auf diese Weise muss ich mich nicht wirklich darum kümmern, den Pfad zur Python-Exe in meinen .NET-Code aufzunehmen.

Während der Entwicklung richten Tester die PATH-Variable jetzt nur noch manuell ein. Aber irgendwann werde ich ein Windows-Installationsprogramm (exe) erstellen lassen, das das Add-In installiert, alle Python-Abhängigkeiten installiert und alle erforderlichen PATH-Variablen festlegt. Dafür verwende ich das Nullsoft Scriptable Install System (NSIS) , ein Open-Source-System zum Erstellen von Windows-Installationsprogrammen. Hier ist der Code, den ich bisher ausgearbeitet habe, der ziemlich rau ist. Grundsätzlich wird in der Registrierung geprüft, ob die interessierenden PATH-Variablen vorhanden sind, und wenn nicht, werden sie hinzugefügt. Muss natürlich als Administrator ausgeführt werden.

include "StrFunc.nsh"
!include "LogicLib.nsh"

/*
  Name: VIESORE_Installer.nsi
  Author: Chad Cooper, CAST
  Date: 7/16/2012
  Purpose: NSIS installer script for .exe creation by NSIS. Installs VIESORE components and sets up environment.
*/

Name "VIESORE"
Caption "VIESORE Installer"
Outfile "VIESOREInstaller.exe"

RequestExecutionLevel admin

# Initialize functions
${StrLoc}
# Initialize user variables
Var path

Section "Set SYSTEM PATH environmental variables"
    ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path"
    ${StrLoc} $1 $0 "C:\Python26\ArcGIS10.0" ">"
    ${StrLoc} $2 $0 "C:\Python26\ArcGIS10.0\Scripts" ">"
        ${StrLoc} $3 $0 "C:\Python26\ArcGIS10.0\Lib\site-packages" ">"
        ${StrLoc} $4 $0 "C:\Program Files\e-on software\Vue 10 Infinite\Application" ">"
        # Test to see if env vars exist in current system PATH, if not add them to $path variable
        ${If} $3 == ""
                StrCpy $path "C:\Python26\ArcGIS10.0\Lib\site-packages"
        ${EndIf}
        ${If} $2 == ""
                StrCpy $path "C:\Python26\ArcGIS10.0\Scripts;$path"
        ${EndIf}
        ${If} $1 == ""
                StrCpy $path "C:\Python26\ArcGIS10.0;$path"
        ${EndIf}
        ${If} $4 == ""
                StrCpy $path "C:\Program Files\e-on software\Vue 10 Infinite\Application;$path"
        ${EndIf}
        DetailPrint "$path written to system PATH"
    WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" "$0;$path"
    ReadRegStr $5 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path"
    DetailPrint "New Path: $5"
SectionEnd

Auch hier wird der Pfad zur ArcGIS Python-Exe nicht gefunden, aber Sie können dem Endbenutzer die Befugnis geben, diese ordnungsgemäß und einfach festzulegen.

Chad Cooper
quelle
+1 Ich stimme dieser Empfehlung voll und ganz zu --- auf hoher Ebene sagt Chad: "Arbeite das Problem nicht rückwärts, um die Python-Instanz von Arc abzuleiten, sondern benutze ein Installationsprogramm und überlasse es dem SysAdmin, um den richtigen Python zu erstellen Beispiel." @ChadCooper, gibt Ihnen NSIS eine UI-Steuerung, damit Sie diese Standardpfade überschreiben können, wenn Sie dies wünschen? Ich sehe das nicht im Code, aber ich wette, es ist da.
Elrobis
@elrobis - Ich wette, Sie können vorhandene überschreiben / bearbeiten / ändern - NSIS ist sehr konfigurierbar und Sie können ein ziemlich geschicktes Installationsprogramm erstellen - Sie müssen nur den Code herausfinden, um es zu schreiben.
Chad Cooper
Das Erstellen eines Installationsprogramms für ein Add-In scheint nur ein bisschen verrückt zu sein. Welche Änderungen müssten Sie auch vornehmen, um 10.1, 10.2 usw. sowie 10.0 zu unterstützen?
blah238
@ blah238 - Ja, es scheint verrückt zu sein, aber mein Installer für dieses spezielle Projekt wird viel mehr tun, wie bereits erwähnt. Mein Add-In ist ausschließlich für 10.0. Vermutlich können Sie für verschiedene Versionen von ArcGIS die Registrierung überprüfen, um festzustellen, welche Version installiert ist, und dann entsprechend vorgehen.
Chad Cooper