2012-09-12 15 views
10

मेरे पास निम्न छोटा सी # अनुप्रयोग है जो "jconsole.exe" लॉन्च करने का प्रयास करता है, जो मेरी मशीन पर C: \ Programs \ jdk16 \ bin में स्थित है।प्रक्रिया। स्टार्ट() और पाथ पर्यावरण परिवर्तनीय

using System; 
using System.Diagnostics; 

namespace dnet { 
    public class dnet { 
    static void Main(string[] args) { 
     try { 
     Process.Start("jconsole.exe"); 
     Console.WriteLine("Success!"); 
     } catch (Exception e) { 
     Console.WriteLine("{0} Exception caught.", e); 
     } 
    } 
    } 
} 

मेरी पथ वातावरण चर

c:\windows;c:\windows\sytem32;c:\programs\jdk16\bin 

पर सेट है यह पूरी तरह काम करता है। हालांकि, पथ वातावरण चर (ध्यान दें के बीच दो बैकस्लैश "c:" और "कार्यक्रमों")

c:\windows;c:\windows\sytem32;c:\\programs\jdk16\bin 

पर सेट है, यह एक Win32 अपवाद के साथ विफल रहता है।

System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified 
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo) 
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo) 
at dnet.dnet.Main(String[] args) 

दिलचस्प है, एक ही कमांड प्रॉम्प्ट जहाँ मैं नेट कार्यक्रम चलाने के लिए और अपवाद मिल में, मैं बस "jconsole.exe" लिख सकते हैं और कार्यक्रम शुरू कर देंगे। विंडोज़ को पैथ में डबल बैकस्लैश के साथ एक्जिक्यूटिव खोजने में कोई परेशानी नहीं है, लेकिन Process.Start() करता है।

पीएटीएच में अतिरिक्त बैकस्लैश समस्या क्यों पैदा कर रहा है, और मैं समस्या के आसपास कैसे हो सकता हूं? मुझे नहीं पता कि मैं जिस निष्पादन योग्य को कॉल करना चाहता हूं वह रनटाइम पर स्थित होगा, इसलिए मैं पैथ चर पर भरोसा करता हूं।

+0

वहाँ एक EXE शुरू करने के लिए दो तरीके हैं, तो आप दोनों तरीकों का परीक्षण कर रहे हैं। आपका ऐप ShellExecuteEx() का उपयोग करता है, कमांड लाइन दुभाषिया CreateProcess() का उपयोग करता है। आप ProcessStartInfo.UseShellExecute प्रॉपर्टी के साथ खेल सकते हैं। इस बारे में चिंता करने में कोई बात नहीं है कि वे पैथ पर्यावरण परिवर्तक को अलग-अलग कैसे समझते हैं, आप जानते हैं कि समस्या को कैसे ठीक किया जाए। –

उत्तर

10

यह सुनिश्चित नहीं है कि समस्या क्यों होती है।

var enviromentPath = System.Environment.GetEnvironmentVariable("PATH"); 

Console.WriteLine(enviromentPath); 
var paths = enviromentPath.Split(';'); 
var exePath = paths.Select(x => Path.Combine(x, "mongo.exe")) 
        .Where(x => File.Exists(x)) 
        .FirstOrDefault(); 

Console.WriteLine(exePath); 

if (string.IsNullOrWhiteSpace(exePath) == false) 
{ 
    Process.Start(exePath); 
} 

मैं एक पैरा जो मुझे इस समाधान के लिए विचार प्रदान किया मिला: हालांकि, मैं एक समाधान है कि मेरे मशीन पर काम करता है के बारे में सोच सकते हैं। documentation for Process.Start

आप पथ चर उद्धरण का उपयोग कर अपने सिस्टम में घोषित किया है से, आप पूरी तरह से उस पथ अर्हता प्राप्त जब किसी भी प्रक्रिया है कि स्थान में पाया शुरू करने चाहिए। अन्यथा, सिस्टम पथ नहीं मिलेगा। उदाहरण के लिए, यदि सी: \ mypath आपके पथ में नहीं है, और आप इसे उद्धरण अंकों का उपयोग करके जोड़ते हैं: पथ =% पथ%; "c: \ mypath", आपको c: \ mypath में किसी भी प्रक्रिया को पूरी तरह अर्हता प्राप्त करनी होगी इसे शुरू करना

तरह से मैंने इसे पढ़ा है, भले ही PATH चर एक मान्य पथ कि Windows का उपयोग करने में सक्षम है निहित, Process.Start इसका इस्तेमाल करने में असमर्थ है और पूरी तरह से योग्य पथ की जरूरत है।

+0

दस्तावेज़ अमिथ से अनुच्छेद को हाइलाइट करने के लिए धन्यवाद। मैं इसे उद्धरण के साथ पथ में केवल प्रविष्टियों को प्रभावित करने के रूप में व्याख्या करता हूं, लेकिन मुझे आपके सामान्यीकरण को पसंद है कि आप PATH पर्यावरण चर का सही उपयोग करने के लिए Process.Start() पर भरोसा नहीं कर सकते। एक दिलचस्प बात के रूप में, मैंने अपने पथ को 'c: \ windows \ system32; c: \ windows;" c: \ programs \ jdk16 \ bin "', और Process.Start() को jconsole.exe को खोजने में सक्षम था कोई अतिरिक्त मदद ऐसा लगता है कि दस्तावेज़ों का क्या मतलब है, PATH का उपयोग कर Process.Start() के बारे में, इसलिए मुझे वास्तव में इस पर भरोसा नहीं है। :) –

3

यदि आप पहले ProcessStartInfo बनाते हैं तो आप इसे हल कर सकते हैं।

ProcessStartInfo psi = new ProcessStartInfo("jconsole.exe"); 
StringDictionary dictionary = psi.EnvironmentVariables; 

// Manipulate dictionary... 

psi.EnvironmentVariables["PATH"] = dictionary.Replace(@"\\", @"\"); 
Process.Start(psi); 

आपको अपने आप को यह काम करने के लिए पैथ में हेरफेर करने का तरीका पता होना चाहिए। लेकिन इससे आपके पाथ वैरिएबल के साथ होने वाले किसी भी मुद्दे को हल करना चाहिए।

+1

[EnvironmentVariables प्रॉपर्टी] को बदलने के बाद (http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.environmentvariables.aspx), आपको [UseShellExecute प्रॉपर्टी] सेट करना होगा (http : //msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.useshellexecute.aspx) झूठी करने के लिए। हालांकि, यदि UseShellExecute गलत है, तो मुझे [FileName प्रॉपर्टी] (http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.filename) के लिए पूरी तरह से योग्य पथ निर्दिष्ट करना होगा, किस प्रकार की हार पथ बदलने का उद्देश्य। –

+0

फिर भी 'UseShellExecute' पृष्ठ पर बहुत ही उदाहरण में वे पूरी तरह योग्य' फ़ाइल नाम 'नहीं देते हैं और' UseShellExecute = false; 'का उपयोग करते हैं। मैंने इसे झूठी जगह पर सेट करने की कोशिश की है और केवल एक एक्सई को बुलाया है जो केवल मेरे पैथ में पाया जा सकता है और यह अभी शुरू होता है। – Chrono

3

स्वीकृत उत्तर सही नहीं है।

cmd.exe पहले निष्पादन योग्य एक्सटेंशन वाले एप्लिकेशन पाएंगे।
तो जब आपके पास puma और puma.batC:\Ruby\bin\ में फ़ाइलें हैं, तो buma.bat को प्यूमा पर प्राथमिकता दी जाएगी।

यदि आप c:\ruby\bin\puma.batc:\redmine से शुरू करते हैं, तो यह वर्तमान कार्यशील निर्देशिका c:\ruby\bin के साथ प्यूमा शुरू करेगा, और आपका वेब एप्लिकेशन काम करेगा।
यदि आप सीधे c:\ruby\bin\puma शुरू करते हैं, तो यह वर्तमान कार्य निर्देशिका के साथ c:\redmine में प्यूमा शुरू करेगा और बाद में विफल हो जाएगा।

तो सही संस्करण अधिक या कम इस तरह दिखता है:

// FindAppInPathDirectories("ruby.exe"); 
public string FindAppInPathDirectories(string app) 
{ 
    string enviromentPath = System.Environment.GetEnvironmentVariable("PATH"); 
    string[] paths = enviromentPath.Split(';'); 

    foreach (string thisPath in paths) 
    { 
     string thisFile = System.IO.Path.Combine(thisPath, app); 
     string[] executableExtensions = new string[] { ".exe", ".com", ".bat", ".sh", ".vbs", ".vbscript", ".vbe", ".js", ".rb", ".cmd", ".cpl", ".ws", ".wsf", ".msc", ".gadget" }; 

     foreach (string extension in executableExtensions) 
     { 
      string fullFile = thisFile + extension; 

      try 
      { 
       if (System.IO.File.Exists(fullFile)) 
        return fullFile; 
      } 
      catch (System.Exception ex) 
      { 
       Log("{0}:\r\n{1}", 
        System.DateTime.Now.ToString(m_Configuration.DateTimeFormat, System.Globalization.CultureInfo.InvariantCulture) 
        , "Error trying to check existence of file \"" + fullFile + "\"" 
       ); 

       Log("Exception details:"); 
       Log(" - Exception type: {0}", ex.GetType().FullName); 
       Log(" - Exception Message:"); 
       Log(ex.Message); 
       Log(" - Exception Stacktrace:"); 
       Log(ex.StackTrace); 
      } // End Catch 

     } // Next extension 

    } // Next thisPath 


    foreach (string thisPath in paths) 
    { 
     string thisFile = System.IO.Path.Combine(thisPath, app); 

     try 
     { 
      if (System.IO.File.Exists(thisFile)) 
       return thisFile; 
     } 
     catch (System.Exception ex) 
     { 
      Log("{0}:\r\n{1}", 
       System.DateTime.Now.ToString(m_Configuration.DateTimeFormat, System.Globalization.CultureInfo.InvariantCulture) 
       , "Error trying to check existence of file \"" + thisFile + "\"" 
      ); 

      Log("Exception details:"); 
      Log(" - Exception type: {0}", ex.GetType().FullName); 
      Log(" - Exception Message:"); 
      Log(ex.Message); 
      Log(" - Exception Stacktrace:"); 
      Log(ex.StackTrace); 
     } // End Catch 

    } // Next thisPath 

    return app; 
} // End Function FindAppInPathDirectories