मुझे कैसे पता चलेगा कि कोई प्रक्रिया चल रही है?


155

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

जवाबों:


252

यह नाम के साथ करने का एक तरीका है:

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

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

4
@MatthewD: C # if/elseस्टेटमेंट्स जो लंबाई में केवल एक लाइन हैं, ब्लॉक स्टेटमेंट को इंगित करने के लिए घुंघराले ब्रेस की आवश्यकता नहीं है। यह भी foreachऔर forबयानों के लिए जाता है । यह कोडिंग शैली को उबालता है।
हॉलमैनैक

मैंने इस पर कुछ शोध भी किया, उस जानकारी को पाया, लेकिन मैंने forजानकारी नहीं देखी । वर्षों के c # .net देव और मैंने इस शैली को कभी नहीं देखा। जैसे वे कहते हैं, "आप हर दिन कुछ नया सीखते हैं"। पोस्ट और उत्तर के लिए धन्यवाद ..
मैथ्यूड

3
@MatthewD हाँ, यह वास्तव में अधिकांश भाषाओं (जैसे जावा) के लिए जाता है। आम तौर पर इन जैसे वन-लाइनर्स से बचने के लिए यह अच्छा अभ्यास है और हमेशा घुंघराले ब्रेसिज़ लगाते हैं, क्योंकि हमेशा एक मौका होता है कि आपको भविष्य में और अधिक स्टेटमेंट्स जोड़ने पड़ सकते हैं, इस मामले में ब्रेसिज़ पहले से ही होंगे जब आपको उनकी आवश्यकता होगी। लेकिन इस तरह की चीजों के लिए, यदि आप 100% सुनिश्चित हैं कि आपको केवल एक कथन की आवश्यकता है, तो यह करना ठीक है और वाक्यविन्यास रूप से मान्य है।
डेविड मोर्डिगल

1
यदि आपको प्रक्रिया नहीं मिल रही है, तो एक्सटेंशन हटाने का प्रयास करें। (Ex: .exe)
DxTx

28

यह सबसे सरल तरीका है जो मैंने रिफ्लेक्टर का उपयोग करने के बाद पाया। मैंने उसके लिए एक एक्सटेंशन विधि बनाई:

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वर्ग आंतरिक है ...


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

16

समकालिक समाधान:

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.");
}

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

8

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

यहाँ उसने जो कुछ पोस्ट किया है उसका संशोधित संस्करण है।

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

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


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

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

यह हर बार FirstHandledException इवेंट हैंडलर को ट्रिगर करेगा। अपने लॉग वहाँ दोस्त को स्पैम करने का तरीका।
विलंबता

6

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

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

3

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

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

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

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


1

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


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

0

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

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

यदि आप ब्लॉक करना चाहते हैं तो आप EnableRaisingEvents को भी सेट कर सकते हैं और बाहर निकलने की घटना (जो asychronously भेजी जाती है) या WaitForExit () को कॉल कर सकते हैं।


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
At openApplication.HasExited(), HasExited कोई फ़ंक्शन नहीं है। सही तरीका होगा openApplication.HasExited
caiosm1005

0

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

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


0

इससे जुड़ी कई समस्याएं हैं, जैसा कि अन्य को आंशिक रूप से पता है:

  • किसी भी उदाहरण के सदस्यों को धागा सुरक्षित होने की गारंटी नहीं है। मतलब वहाँ दौड़ की स्थिति है जो वस्तु के गुणों का मूल्यांकन करने की कोशिश करते समय स्नैपशॉट के जीवनकाल के साथ हो सकती है।
  • प्रोसेस हैंडल एसीसी डेनियड के लिए Win32Exception को फेंक देगा जहां इस और ऐसे अन्य गुणों के मूल्यांकन की अनुमति नहीं है।
  • ISN'T RUNNING स्थिति के लिए, इसके कुछ गुणों का मूल्यांकन करने का प्रयास करते समय एक ArgumentException को भी उठाया जाएगा।

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

var x = obj.GetType().GetProperty("Name", BindingFlags.NonPublic | BindingFlags.Instance);

आप स्नैपशॉट के लिए Win32 कोड पिन कर सकते हैं या आप WMI का उपयोग कर सकते हैं जो धीमा है।

HANDLE CreateToolhelp32Snapshot(
  DWORD dwFlags,
  DWORD th32ProcessID
);

एक अन्य विकल्प OpenProcess के लिए होगा / CloseProcess, लेकिन आप अभी भी अपवाद पहले की तरह ही फेंके जाने के साथ एक ही समस्या आने पर होगा।

WMI के लिए - OnNewEvent.Properties ["?"]:

  • "ParentProcessID"
  • "ProcessID"
  • "प्रक्रिया का नाम"
  • "SECURITY_DESCRIPTOR"
  • "सत्र आईडी"
  • "सिड"
  • "TIME_CREATED"

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

इसके अलावा, आप हर बार प्रक्रिया की जाँच के लिए एक टाइमर का उपयोग कर सकते हैं


3
चारों ओर अन्य रास्ता नहीं होगा? अगर लंबाई == 0 का मतलब है कि काम नहीं कर रहा है?
जय जैकब्स

इसका जवाब पैट्रिक
डेसजार्डिंस

लंबाई के आसपास इसका दूसरा तरीका> 0 का मतलब प्रक्रियाएं हैं।
हसीबी मीर

इसमें त्रुटि हो सकती है, ( length == 0प्रदर्शित होना चाहिए Not Working) लेकिन फिर भी काम हो जाता है।
मोमोरो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.