2008-12-11 4 views
17

पर कॉल करने के बाद WaitForExit पर सेवा लटकती है मेरे पास ऐसी सेवा है जो कभी-कभी बैच फ़ाइल को कॉल करती है। बैच फ़ाइल 5-10 सेकंड लेता है निष्पादित करने के लिए:बैच फ़ाइल

System.Diagnostics.Process proc = new System.Diagnostics.Process(); // Declare New Process 
    proc.StartInfo.FileName = fileName; 
    proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; 
    proc.StartInfo.CreateNoWindow = true; 
    proc.Start(); 
    proc.WaitForExit(); 

फ़ाइल मौजूद है और कोड काम करता है जब मैं इन-सांत्वना एक ही कोड चलाते हैं। हालांकि जब यह सेवा के अंदर चलता है, तो यह WaitForExit() पर लटकता है। जारी रखने के लिए मुझे प्रक्रिया से बैच फ़ाइल को मारना होगा। (मुझे यकीन है कि फ़ाइल मौजूद है, क्योंकि मैं इसे प्रक्रिया सूची में देख सकता हूं।)

मैं इस लटकन को कैसे ठीक कर सकता हूं?

अद्यतन # 1:

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

"C: \ EnterpriseDB \ Postgres \ 8.3 \ बिन \ pg_dump.exe" मैं -h स्थानीय होस्ट -p 5432 यू postgres एफ पी -एक डी -v -f "c: \ backupcasecocher \ । backupdateevent2008.sql "आयकर" \ "सार्वजनिक \" \ "dateevent \" "" DbTest "

अन्य बैच फ़ाइल है:

" C: \ EnterpriseDB \ Postgres \ 8.3 \ बिन \ vacuumdb.exe "-U postgres -d डीबीटेस्ट

मैंने पथ की जांच की है और postgresql पथ ठीक है। आउटपुट निर्देशिका मौजूद है और अभी भी सेवा के बाहर काम करता है। कोई विचार?

अद्यतन # 2: proc.StartInfo.FileName के लिए और proc.StartInfo.Arguments के सभी मापदंडों कहा:

बैच फ़ाइल का पथ के बजाय

, मैं "\ EnterpriseDB \ Postgres \ 8.3 \ बिन \ pg_dump.exe सी 'लिखा था। परिणाम अपरिवर्तित हैं, लेकिन मुझे प्रक्रिया विंडो में pg_dump.exe दिखाई देता है। फिर यह केवल सेवा के अंदर होता है।

# 3 अद्यतन:

मैं सेवा व्यवस्थापक समूह में एक उपयोगकर्ता के साथ, कोई लाभ नहीं हुआ चल चुके हैं।

मैं एक साधारण सेवा बनाया ईवेंट लॉग में एक निशान लिख सकते हैं और एक बैच फ़ाइल है कि यह में "dir" शामिल हैं निष्पादित करने के लिए: मैं सेवा के उपयोगकर्ता नाम और पासवर्ड

अद्यतन # 4 के लिए null बहाल। अब यह proc.Start(); पर लटका होगा - मैंने स्थानीय सिस्टम से खाता बदलने की कोशिश की है उपयोगकर्ता और मैंने प्रशासक उपयोगकर्ता और पासवर्ड सेट किया है, अभी भी कुछ नहीं।

proc.StartInfo.FileName     = target; 
proc.StartInfo.RedirectStandardError = true; 
proc.StartInfo.RedirectStandardOutput = true; 
proc.StartInfo.UseShellExecute   = false; 

proc.Start(); 

proc.WaitForExit 
    (
     (timeout <= 0) 
      ? int.MaxValue : timeout * NO_MILLISECONDS_IN_A_SECOND * 
       NO_SECONDS_IN_A_MINUTE 
    ); 

errorMessage = proc.StandardError.ReadToEnd(); 
proc.WaitForExit(); 

outputMessage = proc.StandardOutput.ReadToEnd(); 
proc.WaitForExit(); 

मैं अगर है कि आप के लिए चाल करना होगा पता नहीं है, लेकिन मैं इसे फांसी की समस्या नहीं है:

+0

@nzpcmad: ओपी के टैग को बदलने का विचार आपको पृथ्वी पर कहां मिला? – GEOCHET

+0

मैं nzpcmad नहीं हूं, लेकिन मेरा अनुमान है: चूंकि वह कहता है "मेरे पास एक webservice है", मुझे लगता है कि उसके पास एक वेब सेवा (.asmx) है और विंडोज सेवा नहीं है। –

+0

@ माइकल: मैं नहीं देखता कि ओपी का टैग कैसे वारंट/बदल रहा है। – GEOCHET

उत्तर

28

यहाँ क्या मैं बैच फ़ाइलों को निष्पादित करने का उपयोग करें।

+1

हाँ के साथ कोई नमूना कोड .. क्या केविन कहते हैं। वह stderr और stdout को रीडायरेक्ट कर रहा है जैसा कि मैंने उल्लेख किया है, लेकिन बड़े अंतरों में से एक यह है कि वह "UseShellExecute" को गलत पर सेट कर रहा है, जो आपको Vista पर आने पर विचार करना है ... अच्छा जवाब केविन ... लैरी – LarryF

+0

मुझे आज़माएं! मैं वापस आऊंगा –

+3

एक सेकंड में कोई मिलीसेकंड क्यों नहीं हैं? –

3

बैच फ़ाइल क्या करती है? क्या आप निश्चित हैं कि बैच फ़ाइल निष्पादित करने के लिए पर्याप्त निजीकरण के साथ प्रक्रिया शुरू हो रही है? सेवाओं को सीमित किया जा सकता है जो उन्हें करने की अनुमति है।

इसके अलावा, अगर आप प्रतिलिपि आदेश usin एक फ़ाइल है कि आप की तरह कुछ करना अधिलेखित करने के लिए की तरह कुछ कर रहे हैं सुनिश्चित करें:

echo Y | copy foo.log c:\backup\ 

इसके अलावा, सुनिश्चित करें कि आप बैच आदेश, आदि के लिए पूरा पथ उपयोग कर रहे हैं यदि बैच फ़ाइल किसी प्रकार के "कंसोल" मोड में एक जीयूआई ऐप लॉन्च कर रही है, तो यह भी एक मुद्दा हो सकता है। याद रखें, सेवाओं में "डेस्कटॉप" नहीं है (जब तक कि आप किसी भी प्रकार की विंडो या संदेश बॉक्स को आकर्षित करने के लिए "डेस्कटॉप के साथ इंटरैक्ट" सक्षम नहीं करते)। आपके प्रोग्राम में, आप stdout और stderr पाइप खोलना चाहेंगे और निष्पादन के दौरान उनसे पढ़ सकते हैं यदि आपको कोई त्रुटि संदेश या कुछ भी मिल रहा है।

वेब सर्विसेज शायद आईयूएसआर खाता, या अनाम खाता, जो कभी भी हो, के रूप में निष्पादित कर रहे हैं, ताकि आपके लिए कोई समस्या हो। यदि यह कंसोल में चलाए जाने पर काम करता है, तो यह पहला कदम है। :)

मुझे सिस्टम.डिग्नोस्टिक्स को याद नहीं है। केवल डीबग में उपलब्ध हैं या नहीं। शायद नहीं, लेकिन उनमें से कुछ हो सकता है। मुझे इसके लिए जांच करनी होगी।

आशा है कि यह आपको कुछ विचार देता है।

लैरी

3

pg_dump.exe शायद उपयोगकर्ता इनपुट के लिए उत्साह है। क्या इस डेटाबेस को प्रमाणीकरण की आवश्यकता है? क्या आप किसी भी पर्यावरण चर पर भरोसा कर रहे हैं जो सेवा के लिए उपस्थित नहीं होगा? मुझे pg_dump नहीं पता लेकिन इनपुट के लिए संकेत देने के अन्य संभावित कारण क्या हैं?

+0

मैं cmd.exe की कमांड लाइन से यह आदेश कर सकता हूं और यह बिना संकेत के काम करता है। –

3

अगले चरण में मैं डीबगर को आग लगाना चाहता हूं, और देख सकता हूं कि आप यह बता सकते हैं कि कार्यक्रम क्या इंतजार कर रहा है। यदि आप असेंबली में डिबगिंग पर निष्कासित हैं, तो आप ProcExp, FileMon, आदि जैसे टूल का उपयोग करके क्या हो रहा है,

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

यदि आप बेताब हैं, तो आप अपनी बैच फ़ाइल के बजाय cmd.exe लॉन्च करने का प्रयास कर सकते हैं। फिर, cmd.exe के cmd लाइन पैरामीटर का उपयोग करके, आप बैच फ़ाइल को प्रारंभ कर सकते हैं। यदि आप डेस्कटॉप के साथ इंटरैक्ट चालू करते हैं, तो यह संभवतः आपको वास्तविक आउटपुट देखने के लिए एक cmd प्रॉम्प्ट विंडो देगा।

cmd.exe पर पूरी मदद के लिए, बस cmd/टाइप करें? किसी भी कमांड प्रॉम्प्ट पर।

लैरी

+0

अब बैच फ़ाइल में केवल "डीआईआर" है। मैंने असली परियोजना के बाहर एक समाधान बनाया है और मैं निष्पादित करने की कोशिश कर रहा हूं। यह अभी भी लटका है। मेरे पास अंतिम लॉग proc.Start() विधि से ठीक पहले है। –

1

यहां समाधान है। समाधान स्पष्ट नहीं है क्योंकि मैंने कोड को इतनी बार बदल दिया है और अब यह काम कर रहा है!

मैंने उपयोगकर्ता के खाते का उपयोग करने का प्रयास किया है, और यह काम नहीं किया है। स्थानीय सिस्टम का प्रयोग करें। यहां कोड है जो निष्पादित करता है, ज्यादातर केविन ने मुझे क्या दिया।

  System.Diagnostics.Process proc = new System.Diagnostics.Process(); 
      proc.StartInfo.FileName = fileName; 
      proc.StartInfo.RedirectStandardError = true; 
      proc.StartInfo.RedirectStandardOutput = true; 
      proc.StartInfo.UseShellExecute = false; 


      proc.Start(); 
      proc.WaitForExit(); 
      output1 = proc.StandardError.ReadToEnd(); 
      proc.WaitForExit(); 
      output2 = proc.StandardOutput.ReadToEnd(); 
      proc.WaitForExit(); 

धन्यवाद, मैं सभी को अप-वोट दूंगा और केविन को स्वीकार करूंगा क्योंकि वह शुरुआत से ही मेरी मदद करता है। बहुत अजीब क्योंकि यह अब काम करता है ...

+0

यह अच्छा और अच्छा है यदि आप केवल एक-एक चीज़ कर रहे हैं, लेकिन कृपया स्थानीय सिस्टम के रूप में स्क्रिप्ट चलाने वाले सॉफ़्टवेयर को शिप न करें, –

+0

हाँ सुरक्षित करना बहुत मुश्किल है। इसके बजाय, उन्हें सक्रिय स्क्रिप्ट निष्पादित करें, इसलिए हमलावर कम से कम गेंद रोलिंग प्राप्त करने के लिए vbScript का उपयोग कर सकता है ... :) (बेशक, आप सभी को यह जानना है कि मैं सिर्फ kiddding हूँ। मुझे खुशी है कि वह अपना समाधान मिला, सिर्फ पागल है कि केविन इसे पहले मिला है। हे ..) :) जे/के फिर से। अब कोई मुझ पर पागल नहीं हो रहा है ... – LarryF

1

दाओक, ऐसा लगता है कि आपके द्वारा बदला गया एकमात्र चीज प्रारंभिक WaitForExit() पर टाइमआउट अवधि थी। आपको इसके बारे में बहुत सावधान रहना होगा। अगर DOES आपकी सेवा को लटकाता है, तो यह कभी वापस नहीं आएगा (और अच्छी तरह से, यह आपके लिए बहुत अधिक काम है .. हे), लेकिन यह अंतिम उपयोगकर्ताओं के लिए अच्छा नहीं होगा ...

अब, तुम्हें पता है शायद कि क्या यह लटका पैदा, आप इसमें कुछ डीबग कर सकते हैं और पूर्ण समाधान खोजने के ...

यही कारण है, या कुछ धागा है कि आप निगरानी कर सकते हैं में इस बंद स्पिन, और अगर मारने यह बहुत लंबा लटका है।

बस मेरे 2 सेंट मूल्य, जो आम तौर पर पूरी तरह से नहीं है। ;)

11

सिस्टम का उपयोग कर; System.Collections.Generic का उपयोग कर ; System.Linq का उपयोग कर ; System.Text का उपयोग कर ; System.Diagnostics का उपयोग कर ; नाम स्थान वीजी { वर्ग VGe { [STAThread] static void मुख्य (स्ट्रिंग [] args) { प्रक्रिया PROC = बातिल; {
स्ट्रिंग targetDir = string.Format (@ "डी: \ एडाप्टर \ सेटअप"); // यह वह जगह है जहां mybatch.bat proc = new Process() है; proc.StartInfo.WorkingDirectory = targetDir; proc.StartInfo.FileName = "mybatch.bat"; proc.StartInfo.Arguments = string.Format ("10"); // यह तर्क proc.StartInfo.CreateNoWindow = false; proc.Start(); proc.WaitForExit(); } पकड़ (अपवाद पूर्व) { कंसोल। राइटलाइन ("अपवाद हुआ: {0}, {1}", ex.Message, ex.StackTrace.ToString()); } } } }

+0

शुरुआत में मेरे पास बहुत कुछ था, है ना? –

4
  string targetDir = string.Format(@"D:\");//PATH 
      proc = new Process(); 
      proc.StartInfo.WorkingDirectory = targetDir; 
      proc.StartInfo.FileName = "GetFiles.bat"; 
      proc.StartInfo.Arguments = string.Format("10");//argument 
      proc.StartInfo.CreateNoWindow = false; 
      proc.Start(); 
      proc.WaitForExit(); 

परीक्षण किया गया, स्पष्ट काम करता है।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^