2008-11-04 14 views
110

जब मुझे System.Diagnostics.Process का संदर्भ मिलता है, तो मुझे कैसे पता चलेगा कि कोई प्रक्रिया वर्तमान में चल रही है या नहीं?मुझे कैसे पता चलेगा कि कोई प्रक्रिया चल रही है या नहीं?

Process[] pname = Process.GetProcessesByName("notepad"); 
if (pname.Length == 0) 
    MessageBox.Show("nothing"); 
else 
    MessageBox.Show("run"); 

आप पाश बाद में हेरफेर के लिए आईडी प्राप्त करने के लिए सभी प्रक्रिया कर सकते हैं:

Process[] processlist = Process.GetProcesses(); 
foreach(Process theprocess in processlist){ 
    Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id); 
} 

उत्तर

185

इस नाम के साथ यह करने के लिए एक तरीका है। लेकिन आपको अपनी प्रक्रिया को खोजने के लिए एक या एक से अधिक विभिन्न मानदंडों का उपयोग करने की आवश्यकता हो सकती है, यह कैसे चल रहा है (यानी एक सेवा या सामान्य ऐप के रूप में, चाहे वह टाइटलबार हो या नहीं)।

+0

यह वही है जो मैं ढूंढ रहा था। भले ही यह एक बहुत पुरानी पोस्ट है, क्या आप मुझे समझाएंगे कि यह वैध सी # कैसे है। मैं इसे संदेह नहीं कर रहा हूं, मुझे लगता है कि यह काम करता है, लेकिन मैंने कभी और नहीं देखा है {}। – MatthewD

+2

@ मैथ्यूड: सी # 'अगर/अन्य 'बयान जो लंबाई में केवल एक पंक्ति हैं, ब्लॉक स्टेटमेंट को इंगित करने के लिए घुंघराले ब्रेसिज़ की आवश्यकता नहीं है। यह 'foreach' और 'के लिए' बयान के लिए भी जाता है। यह कोडिंग शैली के लिए उबलता है। – Hallmanac

+0

मैंने इस पर कुछ शोध भी किया, जानकारी मिली, लेकिन मुझे 'जानकारी' नहीं मिली। सी # नेट देव के वर्षों और मैंने कभी इस शैली को नहीं देखा है। जैसे वे कहते हैं, "आप हर दिन कुछ नया सीखते हैं"। पोस्ट और उत्तर के लिए धन्यवाद .. – MatthewD

1

Process.GetProcesses() जाने का रास्ता है

+0

यदि आप इस विधि को लूप में डालते हैं, तो इसमें बहुत सारे CPU चक्र होते हैं। मैं GetProcessByName() या GetProcessByID() का उपयोग करने की अनुशंसा करता हूं। –

2

यह इस बात पर निर्भर करता है कि आप इस कार्य को कितना विश्वसनीय चाहते हैं। यदि आप जानना चाहते हैं कि आपके पास मौजूद विशेष प्रक्रिया उदाहरण अभी भी चल रहा है और 100% सटीकता के साथ उपलब्ध है तो आप भाग्य से बाहर हैं। कारण यह है कि प्रबंधित प्रक्रिया ऑब्जेक्ट से प्रक्रिया की पहचान करने के केवल 2 तरीके हैं।

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

दूसरा आइटम प्रक्रिया हैंडल है। यह वही समस्या है हालांकि आईडी के रूप में और यह काम करने के लिए और अधिक अजीब है।

यदि आप मध्यम स्तर की विश्वसनीयता की तलाश में हैं तो उसी आईडी की प्रक्रिया के लिए वर्तमान प्रक्रिया सूची की जांच करना पर्याप्त है।

0

शायद (शायद) मैं गलत तरीके से प्रश्न पढ़ रहा हूं, लेकिन क्या आप हैसएक्टेड संपत्ति की तलाश कर रहे हैं जो आपको बताएगा कि आपकी प्रक्रिया ऑब्जेक्ट द्वारा प्रस्तुत प्रक्रिया (या तो सामान्य रूप से या नहीं) है।

यदि आपके पास यूआई के संदर्भ में कोई संदर्भ है, तो आप यह निर्धारित करने के लिए उत्तरदायी संपत्ति का उपयोग कर सकते हैं कि यूआई वर्तमान में उपयोगकर्ता इनपुट का जवाब दे रहा है या नहीं।

आप EnableRaisingEvents भी सेट कर सकते हैं और मौजूदा ईवेंट को संभाल सकते हैं (जिसे अतुल्य रूप से भेजा जाता है) या अगर आप ब्लॉक करना चाहते हैं तो WaitForExit() को कॉल करें।

11

तुल्यकालिक समाधान:

void DisplayProcessStatus(Process process) 
{ 
    process.Refresh(); // Important 


    if(process.HasExited) 
    { 
     Console.WriteLine("Exited."); 
    } 
    else 
    { 
     Console.WriteLine("Running."); 
    } 
} 

अतुल्यकालिक समाधान:

void RegisterProcessExit(Process process) 
{ 
    // NOTE there will be a race condition with the caller here 
    // how to fix it is left as an exercise 
    process.Exited += process_Exited; 
} 

static void process_Exited(object sender, EventArgs e) 
{ 
    Console.WriteLine("Process has exited."); 
} 
+5

पहले विकल्प के लिए: मैं कैसे जान सकता हूं कि प्रक्रिया पहली जगह शुरू हुई थी या नहीं? – reshefm

22

यह सबसे आसान तरीका मैं परावर्तक उपयोग करने के बाद पाया जाता है।

public static class ProcessExtensions 
{ 
    public static bool IsRunning(this Process process) 
    { 
     if (process == null) 
      throw new ArgumentNullException("process"); 

     try 
     { 
      Process.GetProcessById(process.Id); 
     } 
     catch (ArgumentException) 
     { 
      return false; 
     } 
     return true; 
    } 
} 

Process.GetProcessById(processId) विधि ProcessManager.IsProcessRunning(processId) प्रणाली को बुलाती है और मामले की प्रक्रिया मौजूद नहीं है में ArgumentException फेंकता है: मुझे लगता है कि के लिए एक विस्तार विधि बनाया। किसी कारण से ProcessManager कक्षा आंतरिक है ...

+0

यह वास्तव में एक अच्छा जवाब था; हालांकि, आपको तर्क नल अपवाद के माध्यम से नहीं होना चाहिए (क्योंकि एक शून्य संदर्भ अपवाद को किसी भी तरह से फेंक दिया गया होगा और आपने अपवाद के साथ कुछ भी नहीं किया है। इसके अलावा, अगर आप स्टार्ट() शुरू नहीं करते हैं तो आपको एक अवैधऑपरेशन अपवाद मिलेगा विधि या आपने करीबी() विधि का आह्वान किया। मैंने इन दो स्थितियों के लिए खाते में एक और उत्तर पोस्ट किया। – Aelphaeis

0

आप अपनी इच्छित प्रक्रिया के लिए प्रक्रिया प्रक्रिया को तुरंत चालू कर सकते हैं और उस .NET प्रक्रिया ऑब्जेक्ट का उपयोग करके प्रक्रिया को ट्रैक करना जारी रखेंगे (यह तब तक ट्रैकिंग पर टिकेगा जब तक कि आप बंद न करें वह .NET ऑब्जेक्ट स्पष्ट रूप से, भले ही जिस प्रक्रिया को ट्रैक किया गया था, उसकी मृत्यु हो गई है [यह आपको प्रक्रिया के समय को बंद करने में सक्षम है, उर्फ ​​एक्जिटटाइम इत्यादि।])

http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx का हवाला देते हुए:

जब एक संबद्ध प्रक्रिया बाहर निकलता है (अर्थात, जब यह एक सामान्य या असामान्य समाप्ति के माध्यम से आपरेशन प्रणाली द्वारा बंद कर दिया जाता है), सिस्टम के बारे में भंडार प्रशासनिक जानकारी प्रक्रिया और घटक पर लौटता है जिसे WaitForExit कहा जाता था। प्रक्रिया घटक तो कर सकते हैं पहुँच जानकारी है, जो ExitTime भी शामिल है, से बाहर निकल गया प्रक्रिया के लिए हैंडल का उपयोग करके।

क्योंकि जुड़े प्रक्रिया से बाहर निकल गया है, घटक के हैंडल संपत्ति नहीं रह गया है एक मौजूदा प्रक्रिया संसाधन के लिए अंक। इसके बजाय, हैंडल का उपयोग केवल संसाधन संसाधन के बारे में जानकारी ऑपरेटिंग सिस्टम की जानकारी तक पहुंचने के लिए किया जा सकता है। प्रणाली से बाहर निकल गया प्रक्रियाओं के लिए हैंडल कि प्रक्रिया घटकों द्वारा जारी नहीं किया गया है के बारे में पता है, तो यह ExitTime रहता है और स्मृति में जानकारी संभाल जब तक प्रक्रिया घटक विशेष रूप से संसाधनों को मुक्त कर देते। इस कारण से, किसी भी समय आप एक प्रक्रिया उदाहरण के लिए प्रारंभ कहते हैं, बंद कॉल जब जुड़े प्रक्रिया समाप्त कर दिया है और अब आप इस बारे में कोई प्रशासनिक जानकारी की जरूरत है। बंद बाहरी प्रक्रिया में आवंटित स्मृति को मुक्त करता है।

0

मैं Coincoin के समाधान की कोशिश की:
कुछ फ़ाइल को प्रोसेस करने से पहले, मैं इसे एक अस्थायी फ़ाइल के रूप में कॉपी करें और खोलें।
जब मैं लेता हूँ, मैं अनुप्रयोग को बंद करता है, तो यह अभी भी खुला है और हटाने के अस्थायी फ़ाइल:
मैं सिर्फ एक प्रक्रिया चर का उपयोग करें और यह बाद में जाँच करें:

private Process openApplication; 
private void btnOpenFile_Click(object sender, EventArgs e) { 
    ... 
    // copy current file to fileCache 
    ... 
    // open fileCache with proper application 
    openApplication = System.Diagnostics.Process.Start(fileCache); 
} 

बाद में मैंने अनुप्रयोग बंद:

... 
openApplication.Refresh(); 

// close application if it is still open  
if (!openApplication.HasExited()) { 
    openApplication.Kill(); 
} 

// delete temporary file 
System.IO.File.Delete(fileCache); 

यह काम करता है (अब तक)

+3

'openAplication.HasExited()' पर, HasExited एक फ़ंक्शन नहीं है। सही तरीका 'ओपन एप्प्लिकेशंस' हैसएक्टेड 'होगा। – caiosm1005

0
string process="notepad"; 
    if (Process.GetProcessesByName(process).Length == 0) 
    { 
    MessageBox.Show("Working"); 
    } 
    else 
    { 
    MessageBox.Show("Not Working"); 
    } 

अल ताकि आप प्रक्रिया को हर

+1

चारों ओर दूसरी तरफ नहीं होगा? अगर लंबाई == 0 जिसका मतलब काम नहीं कर रहा है? –

+0

उत्तर पैट्रिक Desjardins के समान है: https://stackoverflow.com/a/262291/7713750 – Rekshino

7

reshefm एक बहुत अच्छा जवाब था की जाँच के लिए एक टाइमर का उपयोग कर सकते हैं; हालांकि, यह उस स्थिति के लिए जिम्मेदार नहीं है जिसमें प्रक्रिया शुरू नहीं हुई थी।

यहाँ क्या वह पोस्ट की एक संशोधित संस्करण है।

public static bool IsRunning(this Process process) 
    { 
     try {Process.GetProcessById(process.Id);} 
     catch (InvalidOperationException) { return false; } 
     catch (ArgumentException){return false;} 
     return true; 
    } 

मैं उसकी ArgumentNullException हटा दिया है क्योंकि इसके वास्तव में एक अशक्त संदर्भ अपवाद होना करने के लिए लगता है और यह प्रणाली द्वारा वैसे भी फेंक दिया जाता है और मैं भी स्थिति या करीबी जिसमें प्रक्रिया के साथ शुरू करने के लिए शुरू कर दिया कभी नहीं किया गया था के लिए जिम्मेदार है () प्रक्रिया को बंद करने के लिए विधि का उपयोग किया गया था।

+0

व्यक्तिगत रूप से, मैं बहुत अधिक देखता एक ArgumentNullException जब NullReferenceException की तुलना में लॉग अप अपवाद की समीक्षा करते हैं, क्योंकि ArgumentNullException गलत होने के बारे में और अधिक स्पष्ट है। – Sean

+1

@ सेन मैं सामान्य रूप से आपसे सहमत हैं लेकिन यह एक विस्तार विधि है। मुझे लगता है कि सिंटैक्स दिए गए एक नल पॉइंटर अपवाद को फेंकना अधिक उचित है, यह सिर्फ शून्य वस्तुओं के कॉलिंग विधियों के साथ अधिक संगत लगता है। – Aelphaeis

4

यह एक लाइनर होना चाहिए:

public static class ProcessHelpers { 
    public static bool IsRunning (string name) => Process.GetProcessesByName(name).Length > 0; 
} 
+2

आपको 'की आवश्यकता नहीं है? सच: झूठा 'क्योंकि यह पहले से ही एक बूलियन लौट रहा है। – Melvin

+0

@melvin, धन्यवाद। ठीक कर दिया। – guneysus

0

प्रक्रिया आईडी के आधार पर मौजूदा प्रक्रिया की जाँच के बारे में नेट चौखटे से समर्थित एपीआई के बावजूद, उन कार्यों बहुत धीमी गति से कर रहे हैं। Process.GetProcesses() या Process.GetProcessById/Name() चलाने के लिए इसमें बड़ी मात्रा में CPU चक्र खर्च होते हैं।

आईडी द्वारा चल रही प्रक्रिया की जांच करने के लिए एक बहुत तेज विधि देशी एपीआई OpenProcess() का उपयोग करना है। यदि रिटर्न हैंडल 0 है, तो प्रक्रिया मौजूद नहीं है। यदि हैंडल 0 से अलग है, तो प्रक्रिया चल रही है। इस बात की कोई गारंटी नहीं है कि यह विधि अनुमति के कारण हर समय 100% काम करेगी।

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

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