আমি কীভাবে প্রোগ্রামক্রমে আর্কম্যাপ দ্বারা ব্যবহৃত "পাইথন.এক্স.এই" পথ পেতে পারি


16

আমি সি # তে আর্কম্যাপের একটি অ্যাড-ইন নিয়ে কাজ করছি। সি # কোড থেকে, আমি কিছু পাইথন স্ক্রিপ্ট কার্যকর করেছি। এখন, এই স্ক্রিপ্টটি চালানোর জন্য আমার কাছে হার্ড-কোডড অজগর পথ রয়েছে। তবে এটি বহনযোগ্য নয়। সুতরাং, আমি কোড থেকে পাইথনের পথ নির্বাহযোগ্য এবং এটি ব্যবহার করতে চাই।

প্রশ্ন:

আমি সি # কোড থেকে আর্কম্যাপ দ্বারা ব্যবহৃত পাইথন এক্সিকিউটেবলের পথ কীভাবে পেতে পারি?

সম্পাদনা:

আপনার পরামর্শগুলি থেকে, বর্তমানে আমি পাইথনের পথ পেতে "পথের পরিবেশ" ব্যবহার করছি।

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

কিন্তু একটি সমস্যা আছে:

আমার মেশিনে পাইথনের বিভিন্ন সংস্করণ ইনস্টল হওয়ার পরে, "পাইথন.এক্সে" আমি ব্যবহার করছি এমন কোনও গ্যারান্টি নেই, আর্কজিআইএসও এটি ব্যবহার করে।

"পাইথন.এক্সি" পাথ পেতে অন্য সরঞ্জামটি ব্যবহার করার জন্য আমি প্রশংসা করি না । সুতরাং, আমি সত্যিই ভাবি যে রেজিস্ট্রি কী থেকে কোনও পথ পাওয়ার উপায় আছে কিনা। জন্য "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 ;
}

তবে দ্বিতীয় পদ্ধতিটি ব্যবহার করার আগে আমার অনুমান সম্পর্কে নিশ্চিত হওয়া দরকার। অনুমানগুলি হ'ল:

  1. পাইথনের সাথে যুক্ত "সত্য" অর্থ আর্কজিআইএস দিয়ে পাইথন ইনস্টল করা আছে
  2. আরকজিআইএস 10.0 এবং উচ্চ সংস্করণের রেজিস্ট্রি কী একই প্রক্রিয়াতে লেখা হবে।

আমার অনুমান সম্পর্কে কোনও স্পষ্টতা পেতে দয়া করে আমাকে সহায়তা করুন।



3
আপনি কি কেবল আর্কজিআইএস পাইথন ইপিএইচএইচটি পরিবেশগত পরিবর্তনশীল সেটটি আপনার অ্যাড-ইনের জন্য ইনস্টলেশন প্রয়োজন হতে পারে না?
চাদ কুপার

সমস্ত বলেছে, @ চ্যাডকুপারের চিন্তাভাবনাটি সর্বোত্তম উপায় হতে হবে। পিছনের দিকে কাজ করার চেষ্টা করার পরিবর্তে এটি একবার এবং সবার জন্য ইনস্টল-সময় সেট করুন।
elrobis

@ ইরোবিস: আমি জানি, পথের পরিবেশে পথ নির্ধারণ করা একটি ভাল উপায়। তবে আমি জানতে চেয়েছিলাম যে অজগরটি খুঁজে পাওয়ার কোনও উপায় আছে এবং ব্যবহারকারীর বাধা না দিয়ে সমস্ত কিছু করা যায়।
এমি

@ ব্লাহ 238 আপনার পরামর্শের জন্য ধন্যবাদ। আমি কখনই স্ক্রিপ্ট সরঞ্জাম নিয়ে কাজ করি নি। আমার এটি সম্পর্কে শেখার দরকার হতে পারে
এমি

উত্তর:


2

আমি আপনার দ্বিতীয় কোড উদাহরণটি গ্রহণ করেছি, এটি 64 এবং 32-বিট ওএস উভয় ক্ষেত্রেই কাজ করে দিয়েছি এবং এটি কিছুটা সরলীকৃত করেছি। উইন্ডোজ 7 64-বিটে 10.1 এ আমার জন্য কাজ করে তবে স্পষ্টতই আপনার এটি যতটা সম্ভব পরিবেশের উপর পরীক্ষা করা উচিত এবং আপনার মনে হয় যে কোনও ডিফেন্সিভ প্রোগ্রামিং যাচাই করা দরকার back

পাইথন ছাড়াই আর্কজিআইএস ডেস্কটপ 10.1 ক্লিন-ইনস্টল করার পরে, আমি দেখতে পেয়েছি যে এতে পাইথন 10.x সাবকি অন্তর্ভুক্ত নেই, "পাইথন" ট্রু / ভুয়া মানটি ছেড়ে দিন (এটি এখনও কী তা নিশ্চিত নয়, সম্ভবত ইএসআরআই সহায়তায় যোগাযোগ করুন জানি)।

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

পাইথন সহ একটি ডেস্কটপ 10.1 মেশিনে, এটি ফিরে আসে C:\Python27\ArcGIS10.1\python.exe। পাইথন ব্যতীত একটি ডেস্কটপ 10.1 মেশিনে পাইথন 10.x কী উপস্থিত না থাকায় এটি একটি অবৈধপ্রকাশের অভিজ্ঞতা উত্থাপন করে।

আশা করি আপনি এটি যা বাস্তবায়নের চেষ্টা করছেন তার সাথে এটি আপনাকে সহায়তা করে - যা আশ্চর্যজনক - এখনও আমার কাছে পরিষ্কার নয়।


7

পাইথন এক্সিকিউটেবলের সন্ধানের পরিবর্তে, এই সহায়তা বিষয়টির অবস্থানটি যোগ্যতা ছাড়াই শেল আউট cmd.exeএবং চালানোর পরামর্শ দেয় python.exe। তবে নোট করুন , এটির কাজ করা উচিত কারণ আর্কজিআইএস ডেস্কটপ ইনস্টলারটি সেট আপ করে (সম্পাদনা: সম্প্রতি 10.1-এ পরীক্ষা করা হয়েছে)python.exe এটি ব্যবহারকারীর PATHপরিবেশ পরিবর্তনশীলটিতে যুক্ত হওয়ার পথে নির্ভর করে ies

আর একটি পদ্ধতি হ'ল একটি স্ক্রিপ্ট সরঞ্জাম তৈরি করা এবং এটি আরকোবজেক্টগুলি থেকে চালানো

আপনি যদি সত্যিই আরকজিআইএস এর সংস্করণটির পথে চলে আসেন python.exe, আরকওবজেক্টস + স্ক্রিপ্ট সরঞ্জাম পদ্ধতির প্রসারিত করে, আপনি একটি পাইথন স্ক্রিপ্ট সরঞ্জাম তৈরি করতে পারেন যার একমাত্র আউটপুট এর মান sys.exec_prefix। এটি আর্কজিআইএসের পাইথনের সংস্করণ সম্বলিত ফোল্ডারের পথ C:\Python27\ArcGIS10.1

পার্শ্ব দ্রষ্টব্য : প্রক্রিয়া চলাকালীন এবং কখন নয় sys.executableসেই পথে ফেরত দেয় , এই কারণেই আমি সেই পরিবর্তনশীলটি ব্যবহার করার পরামর্শ দিই না।ArcMap.exepython.exe

আরকোবজেক্টস থেকে স্ক্রিপ্ট সরঞ্জামটি কল করুন এবং প্রত্যাবর্তিত IGeoProcessorResultঅবজেক্ট থেকে আউটপুট পান ।

আপডেট: এখানে একটি নমুনা আর্কম্যাপ অ্যাড-ইন প্রকল্প (ভিএস 2010,। নেট 3.5) রয়েছে যা অ্যাড-ইন-এর মধ্যে প্যাকেজ করা একটি স্ক্রিপ্ট সরঞ্জাম ব্যবহার করে যা কেবল python.exeআর্কেম্যাপের দ্বারা ব্যবহৃত পথটি প্রদর্শন করে : http://wfurl.com/cbd5091

এটি আপনার ক্লিক করা একটি বোতাম এবং এটি একটি বার্তা বাক্সটিকে পপ আপ করে:

বোতাম বার্তা বাক্স

কোডের আকর্ষণীয় বিট:

  • পাইথন লিপি:

    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)
  • সি # ফাংশন:

    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();
    }

2
তবে এই দস্তাবেজটি বলে না যে, আর্কজিআইএস ডেস্কটপ ইনস্টলারটি ব্যবহারকারীর PATH এনভায়রনমেন্ট ভেরিয়েবলের জন্য পাইথন.এক্সে পথ নির্ধারণ করে। সুতরাং এটি সম্ভব হতে পারে যে পাইথনের পথটি PATH পরিবেশে পরিবর্তনশীল নয়। তারপরে এটি একটি ত্রুটি তৈরি করবে। সুতরাং, আমি কীভাবে নিশ্চিত হতে পারি যে ব্যবহারকারীর PATH পরিবেশ পরিবর্তনশীলটিতে অজগর নির্বাহযোগ্য পাথ রয়েছে।
এমি

2
আপনি জীবনের বেশিরভাগ জিনিসগুলির মতো এবং আপনার যা কিছু করা যায় তা গণনা করা অনুমান করা এবং আশা করা যায় যে জিনিসগুলি কার্যকর হয় এবং যখন ফ্যাকব্যাক পরিকল্পনা থাকে না (PATH পরিবেশের পরিবর্তনশীলটিতে এটি যুক্ত করার নির্দেশাবলী সরবরাহ করা হয়)। এটি বলেছে, এটি যদি কোনও সাধারণ ইনস্টলেশন হয় তবে আমি বিশ্বাস করি আর্কজিআইএস ডেস্কটপ ইনস্টলার প্যাথ পরিবেশ পরিবর্তনশীলটিতে সেই পথটি যুক্ত করে vari
blah238

2
আমি অনেকগুলি স্থাপনা দেখেছি যেখানে অর্কগিস-ইনস্টলড পাইথনটি ছিল না। এবং যদি সেখানে দুটি সংস্করণ ইনস্টল করা থাকে এবং 'ভুল' একটি পথে থাকে?

আমি আমার তৃতীয় অনুচ্ছেদে এমন একটি সমাধানের প্রস্তাব দিয়েছিলাম যাতে PATHপরিবেশ পরিবর্তনশীল নির্বিশেষে পাইকনকে আর্কজিআইএসের ইনস্টলেশনটি খুঁজে পাওয়া উচিত ।
blah238

@ blah238 স্ক্রিপ্ট সরঞ্জাম তৈরি করে আমার অ্যাড-ইন কম পোর্টেবল তৈরি করে না বা অন্যদের মেশিনে অ্যাড-ইনগুলির ইনস্টলেশন প্রক্রিয়াটিকে কঠিন করে তোলে?
এমি

6

আপনি কি রেজিস্ট্রি অ্যাক্সেস করতে হবে?

আর্কম্যাপ ইনস্টল করার সময় পাইথন এটি না পেলে এটি ইনস্টল করবে। পাইথন ইতিমধ্যে ইনস্টল করা আছে কিনা তা রেজিস্ট্রিতে দেখায় looks আমি বিশ্বাস করি এর জন্য স্ট্যান্ডার্ড রেজিস্ট্রি অবস্থান হ'ল: কম্পিউটার \ HKEY_LOCAL_MACHINE OF সফটওয়্যার Y পাইথন \ পাইথনকোর 7 2.7 \ ইনস্টলপথটি পথের অবস্থানের ডিফল্ট কী সহ (২.7 হ'ল ১০.১, ২.6 হচ্ছে ১০.০)

কখন কী কারণে এই কীটির মানটি ভুল হবে তা আমি ভাবতে পারছি না তবে আপনি সর্বদা এই পথে যেতে পারেন: রেজিস্ট্রিটির এসরি \ ডেস্কটপ মুরগীর ভিতরে পাইথন অবস্থান। এটি একটি সরল পথ যা আপনি পেতে পারেন এবং তারপরে পাইথন.এক্সে রয়েছে তা নিশ্চিত করার জন্য আরও পাথ তৈরি করতে পারেন। উদাহরণস্বরূপ, 64 বিট মেশিনের কীটি এতে ইনস্টল হয়ে যায়: কম্পিউটার \ HKEY_LOCAL_MACHINE OF সফটওয়্যার ow Wow6432 নোড \ ESRI RI পাইথন 10.1 পাইথনডির কী এবং সম্পর্কিত পথের মান সহ

তবে আমি @ blah238 উত্তরটি পছন্দ করি। আপনার প্রোগ্রাম থেকে কেবল একটি প্রম্পট খুলুন এবং এটি সেখানে চালান। কেন এই কাজ করবে তা আমি কোনও কারণ দেখতে পাচ্ছি না।


2
এই পদ্ধতিরটিও ত্রুটিযুক্ত কারণ এখানে একাধিক পাইথন ইনস্টলেশন থাকতে পারে এবং আর্কজিআইএস দ্বারা ব্যবহৃত কোনটি কোনটি প্রোগ্রামিয়ালি নির্ধারণের কোনও সোজা উপায় নেই। আপনি যদি আরকি চালাচ্ছেন না তবে এটি তাত্পর্যপূর্ণ নয়। তবুও, আমি মনে করি সবচেয়ে শক্তিশালী সমাধানটি রেজিস্ট্রি এবং বেশ কিছুটা যুক্তিযুক্তকে জড়িত করবে। যদিও আমি সেখানে যাচ্ছি না।
blah238

ওয়েল যুক্তিটি নতুন সংস্করণ 2.7 দিয়ে শুরু করতে হবে এবং পিছনের দিকে কাজ করবে। এটি অবশ্যই ব্যর্থ হতে পারে যদি আপনি পাইথনের একটি নতুন সংস্করণ ইনস্টল করেন, তারপরে গিয়ে আর্কজিআইএসের একটি পুরানো সংস্করণ ইনস্টল করে যা পাইথনের একটি পুরানো সংস্করণ ইনস্টল করবে। হ্যাঁ, আমি এই সম্ভাবনাটির সাথে সম্মত হই, তবে এটির সম্ভাবনা নেই (অথবা আপনি কেবল 100% নিশ্চিত হওয়ার জন্য arc10.1 = py2.7, arc10.0 = p2626 ইত্যাদির একটি চেহারা তৈরি করতে পারেন)। আমি যেমন বলেছি, সর্বোত্তম পদ্ধতিটি সম্ভবত কমান্ড প্রম্পটে শেল আউট হবে।
KHibma

@ খিবমা আমি রেজিস্ট্রি দিয়ে অনুসন্ধান করেছি। তবে আমি মনে করি যদি আমি "পাইথন" কীটি দেখি তবে এটি সত্যিই বিরক্তিকর। আমার মেশিনে, দুটি পাইথন সংস্করণ ইনস্টল করা আছে এবং এটি উভয়ই ফিরিয়ে দেয়। আমি মনে করি, "ইএসআরআই" কীটি সন্ধান করা ভাল ধারণা এবং যদি সত্য মানের সাথে "পাইথন" সাবকি থাকে তবে আমি "পাইথনডির" সাবকি মানটি নিতে পারি। এটি আমার ক্ষেত্রে কার্যকর হয় :)
এমি

"ইএসআরআই" কী দ্বারা রেজিস্ট্রিতে অজগর পথটি অনুসন্ধান করার কি এটি ভুল উপায়? অথবা রেসিস্ট্রিতে কী ও মান তৈরি করার জন্য এসরি ব্যবহার করে এমন কোনও পরিবর্তন রয়েছে এবং কোড সম্ভবত এটি পড়তে পারে না
এমি

যখন আমি রেজিস্ট্রিটি "অনুসন্ধান" বলি, তার অর্থ আমি উপরে প্রদত্ত আসল পাথগুলি ব্যবহার করি। যদি না কেউ আরও ভাল জানেন তবে এই রেগ কীগুলির অবস্থান (রেজিস্ট্রিতে) মেশিন থেকে মেশিনে পরিবর্তিত হবে না। সুতরাং আপনি কীগুলি কী কী আছে তা দেখার জন্য কেবল পথগুলি হার্ডকোড করে
রেখেছিলেন

5

[সম্পাদনা] যদিও নির্বাহ setপ্রোগ্রামেটিক্যালি (আউট তাড়িত, নীচে) করেনি কি আমি ব্যবহার চেয়েছিলেন, এটা আরও সহজে সম্পন্ন করা যায় এবং ক্লিনার কোড সহ Environment.GetEnvironmentVariables ()

একটি বিকল্প হ'ল সিস্টেমে প্রতিটি পরিবেশ পরিবর্তনশীল স্ক্যান করা এবং নিম্নলিখিতগুলি প্রমাণ করার চেষ্টা করা:

1) পরিবেশ পরিবর্তনশীল মান একটি ডিরেক্টরি? (এবং যদি তাই হয় ..)

2) যে ডিরেক্টরিতে রয়েছে python.exe?

। নেট প্রক্রিয়া API এর মাধ্যমে কমান্ডটি প্রয়োগ করেset আমি এই প্রোগ্রামটিমেটিকভাবে করতে সক্ষম হয়েছি । কমান্ড, যখন একটি প্যারামিটার ছাড়া ব্যবহার করা, সিস্টেম দ্বারা ব্যবহারের সমস্ত পরিবেশ ভেরিয়েবল ফেরৎ। তাই আমি পরসে পারে, তাহলে থেকে নির্গত stdout- এ ফলাফল সংগঠিত , এবং তাদের পর্দা দেখতে যদি কিছু সবটা (এবং আমি গড় কিছু ) সিস্টেম envionment মাধ্যমে উপলব্ধ পরিণামে তীক্ষ্ন ।setsetpython.exe

আদেশটি নিয়ে আলোচনা করা এই পৃষ্ঠা থেকে set:

সমস্ত বর্তমান পরিবেশের ভেরিয়েবলগুলি প্রদর্শন করতে পরামিতি ছাড়াই এসইটি টাইপ করুন।

চিত্রিত করার জন্য আমি পদ্ধতিগুলির সংমিশ্রণ (এবং একটি সহায়ক শ্রেণি ) লিখেছিলাম যা আমি উপরে আলোচনা করেছি। এগুলি অনুকূলিত করা যেতে পারে এবং তারা কিছু বুলেট-প্রুফিং (ট্রাই..ক্যাচ ইত্যাদি) ব্যবহার করতে পারে তবে কম্পিউটারে যদি কোনও পরিবেশের পরিবর্তনশীল নির্দেশ করে থাকে তবে python.exeএই পদ্ধতির এটি খুঁজে পাওয়া উচিত! আমি কেয়ার করি না যদি Var বলা হয় PATH, ABBRACADABBRAঅথবা যাই হোক না কেন .. যদি এটা স্থানটিকে python.exe, এই এটা হবে।

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

termsপরিবেশের ভেরিয়েবলের নাম, বা এর nমানগুলি (যেমন PATHবেশ কয়েকটি মান থাকতে পারে তবে বেশিরভাগ অন্যান্য ভার্সে কেবল একটি থাকবে) সন্ধানের জন্য আপনি রুটিনটিতে প্রবেশ করার জন্য একটি স্ট্রিংয়ের অ্যারে এখানে রয়েছে । নিশ্চিত করুন যে সমস্ত স্ট্রিংগুলি termsUPPERCASE রয়েছে!

(আমি যখন এটি পরীক্ষা করেছিলাম তখন আমি কেবল "পাইথন" ব্যবহার করি যা C:\Python27\python.exeআমার হোম সিস্টেমে পাওয়া যায় But তবে আপনি সহজে python.exeফিরে আসা কোনও পরীক্ষার্থীর পথ পরীক্ষা করতে চাইলে শর্তগুলির আরও একটি স্ট্রিং অন্তর্ভুক্ত করতে আপনি সহজেই এটি প্রসারিত করতে পারেন --- কারণ উদাহরণস্বরূপ, তারা আর্কজিআইএস বিনে ছিল কিনা তা দেখতে))

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

এবং আমার প্রধান শ্রেণীর নীচে, আমি নিম্নলিখিত সহায়ক শ্রেণি অন্তর্ভুক্ত করেছি :

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

    public string key;
    public string[] values;
}

1
এটি ভঙ্গুর, কারণ ব্যবহারকারী আর্কজিআইএস ডেস্কটপ ইনস্টলারে পাইথন ইনস্টলেশন ডিরেক্টরিটি কাস্টমাইজ করতে পারেন। এছাড়াও PYTHONPATHভেরিয়েবল আপনি চান সেটি নয়।
blah238

@ ব্লাহ 238, কখনও কখনও আপনি যা পেয়েছিলেন তা ভঙ্গুর হয়। আর্কটি পাইথনপথের বিরুদ্ধে ওয়্যার-আপ করে দেখে আমি অবাক হয়েছি। এটি একটি ডিফল্ট 9.2 ইনস্টল। তবুও, ওপি জিজ্ঞাসা করেছিল কীভাবে প্রোগ্রামে আর্কজিআইএস পাইথন.এক্সে যেতে হবে এবং আমি যে পদ্ধতির প্রস্তাব দিয়েছি, ভঙ্গুর বা না, তা করে।
elrobis

আমি ডাউন-ভোটটি বুঝতে পারি না বলে এই উত্তরটি কি আসলেই "কার্যকর নয় "? এটি দুর্দান্ত নাও হতে পারে তবে এটি অবশ্যই একটি বিকল্প, সম্ভবত একটি সাধারণ আরক ইনস্টলের জন্য কাজ করবে এবং খুব কমপক্ষে এটি থ্রেডে সহায়ক কিছু যুক্ত করে - বিশেষত, এটি অজগরটিকে সংযুক্ত করার জন্য একটি ডিফল্ট আর্ক ইনস্টল চিত্রিত করে। চেয়ে একটি এনভায়রনমেন্ট ভেরিয়েবল অপরের সাথে exe PATH
elrobis

দুঃখিত তবে আপনি ভুল। পাইথনপথ ভেরিয়েবলটি পাইথন দ্বারা মডিউলগুলি সন্ধান করতে ব্যবহৃত হয়, পাইথন সন্ধানের জন্য আর্কজিআইএস দ্বারা নয়। লিঙ্কটি পরীক্ষা করুন।
blah238

@ ব্লাহ ২৩৮, আমি মনে করি স্ক্রিনশটটি আমি যে পয়েন্টটি করার চেষ্টা করছিলাম সেটি অপ্রতিরোধ্য / অস্পষ্ট ছিল। (বিশেষত, ওপিকে আমার পরামর্শটি জোর দেওয়ার ইচ্ছুক ছিল না PYTHONPATH, কেবলমাত্র সেই নির্দিষ্ট সিস্টেমে ফিরে যাওয়ার দিকে ইঙ্গিত করার একমাত্র বৈচিত্রময় ঘটনা ঘটেছে python.exe।) যাইহোক, আমি একটি উত্তর সি # কোড উদাহরণ অন্তর্ভুক্ত করার জন্য আমার উত্তরটি ওভারহুলেড করেছি এবং আমি প্রশংসা করব আপনি যদি এখনও এই পদ্ধতির সাথে একমত না হন তা জানার জন্য। ধন্যবাদ / ই।
elrobis

4

উপরের প্রশ্নে আমার মন্তব্যের ভিত্তিতে আমি একটি বিকল্প সমাধান দিতে চাই। একটি বর্তমান প্রকল্পের জন্য, আমি খুব অনুরূপ কিছু করছি; আমার একটি .NET অ্যাড-ইন রয়েছে, যখন ব্যবহারকারী আর্কম্যাপ ইউআইতে একটি বোতাম ক্লিক করেন, একটি পাইথন স্ক্রিপ্ট চলে। আমি আর্কজিআইএস পাইথনের নির্বাহযোগ্য প্রয়োজনীয়তার সাথে একটি প্যাথ এনভায়রনমেন্টাল ভেরিয়েবল সেট রেখেছি, সেইভাবে আমার .NET কোডে পাইথন এক্সে যাওয়ার পথটি অন্তর্ভুক্ত করার বিষয়ে আমাকে সত্যিই চিন্তা করতে হবে না।

এখন, উন্নয়নের সময়, পরীক্ষকরা কেবল PATH ভেরিয়েবলটি ম্যানুয়ালি সেটআপ করছেন। তবে শেষ পর্যন্ত আমার কাছে একটি উইন্ডোজ ইনস্টলার (উদাহরণ) তৈরি হবে যা অ্যাড-ইনটি ইনস্টল করবে, যে কোনও পাইথন নির্ভরতা ইনস্টল করবে এবং প্রয়োজনীয় কোনও প্যাথ ভেরিয়েবল সেট করবে। এর জন্য, আমি নালসফট স্ক্রিপ্টযোগ্য ইনস্টল সিস্টেম (এনএসআইএস) ব্যবহার করছি, উইন্ডোজ ইনস্টলার তৈরির জন্য একটি ওপেন সোর্স সিস্টেম। এখানে আমি এতক্ষণে কিছু কোড তৈরি করেছি যা বেশ রুক্ষ। মূলত, এটি PATH ভেরিয়েবলের আগ্রহের আছে কিনা তা দেখার জন্য এটি রেজিস্ট্রিতে দেখায় এবং যদি তা না হয় তবে এগুলি যুক্ত করে। অবশ্যই অ্যাডমিন হিসাবে চালাতে হবে।

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

সুতরাং, আবারও, এটি আরকজিআইএস পাইথন এক্সের পথ খুঁজে পাচ্ছে না, তবে এটি আপনাকে আপনার শেষ ব্যবহারকারীকে এটি সঠিকভাবে এবং সহজে সেট করার শক্তি দিতে দেয়।


+1 আমি এই সুপারিশটির সাথে পুরোপুরি একমত হয়েছি --- যেখানে উচ্চ-স্তরে চাদ বলছেন "আর্কটির অজগর উদাহরণটি কমাতে পিছনে সমস্যাটি কাজ করবেন না, বরং একজন ইনস্টলার ব্যবহার করুন এবং সঠিক অজগরটি স্থাপনের জন্য সিসএডমিনের কাছে রেখে দিন দৃষ্টান্ত." @ চ্যাডকুপার, এনএসআইএস আপনাকে কি কোনও ইউআই নিয়ন্ত্রণ দেয় যাতে আপনি যদি ডিফল্ট পাথগুলি বেছে নেন তবে ওভাররাইড করতে পারেন? আমি কোড দ্বারা বোঝানো এটি দেখতে পাচ্ছি না তবে আমি এটি বেট করছি।
elrobis

@ ইরোবিস - আমি বাজি ধরতে পারি যে আপনি বিদ্যমানগুলিকে ওভাররাইড / সম্পাদনা / পরিবর্তন করতে পারবেন - এনএসআইএস খুব কনফিগারযোগ্য এবং আপনাকে একটি দুর্দান্ত চতুর ইনস্টলার তৈরি করতে দিতে পারে - আপনি কেবল কোডটি লিখতে হবে।
চাদ কুপার

অ্যাড-ইন-এর জন্য ইনস্টলার তৈরি করা একটু ক্রেজি মনে হয়। এছাড়াও, আপনাকে 10.1, 10.2 ইত্যাদি 10.1, পাশাপাশি 10.1 সমর্থন করার জন্য কী কী পরিবর্তন করতে হবে?
blah238

@ ব্লাহ 238 - হ্যাঁ, এটি পাগল বলে মনে হচ্ছে, তবে এই বিশেষ প্রকল্পের জন্য আমার ইনস্টলারটি কথাবার্তা হিসাবে আরও অনেক কিছু করবে। আমার অ্যাড-ইন 10.0.0 এর জন্য কঠোরভাবে। আমার মনে হয় আর্কজিআইএসের বিভিন্ন সংস্করণগুলির জন্য আপনি কোন সংস্করণ ইনস্টল করা আছে তা দেখতে রেজিস্ট্রিটি পরীক্ষা করতে পারেন, তারপরে সেই অনুযায়ী কাজ করুন।
চাদ কুপার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.