जवाबों:
यह नाम के साथ करने का एक तरीका है:
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);
}
if/else
स्टेटमेंट्स जो लंबाई में केवल एक लाइन हैं, ब्लॉक स्टेटमेंट को इंगित करने के लिए घुंघराले ब्रेस की आवश्यकता नहीं है। यह भी foreach
और for
बयानों के लिए जाता है । यह कोडिंग शैली को उबालता है।
for
जानकारी नहीं देखी । वर्षों के c # .net देव और मैंने इस शैली को कभी नहीं देखा। जैसे वे कहते हैं, "आप हर दिन कुछ नया सीखते हैं"। पोस्ट और उत्तर के लिए धन्यवाद ..
यह सबसे सरल तरीका है जो मैंने रिफ्लेक्टर का उपयोग करने के बाद पाया। मैंने उसके लिए एक एक्सटेंशन विधि बनाई:
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
वर्ग आंतरिक है ...
समकालिक समाधान:
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.");
}
reshefm का बहुत अच्छा जवाब था; हालाँकि, यह उस स्थिति के लिए जिम्मेदार नहीं है जिसमें प्रक्रिया कभी भी शुरू नहीं हुई थी।
यहाँ उसने जो कुछ पोस्ट किया है उसका संशोधित संस्करण है।
public static bool IsRunning(this Process process)
{
try {Process.GetProcessById(process.Id);}
catch (InvalidOperationException) { return false; }
catch (ArgumentException){return false;}
return true;
}
मैंने उसके तर्क को हटा दिया क्योंकि अपवाद वास्तव में एक अशक्त संदर्भ अपवाद माना जाता है और इसे वैसे भी सिस्टम द्वारा फेंक दिया जाता है और मैंने उस स्थिति के लिए भी जिम्मेदार था जिसमें प्रक्रिया को कभी भी शुरू नहीं किया गया था या बंद करने के लिए () विधि का उपयोग किया गया था प्रक्रिया।
यह इस बात पर निर्भर करता है कि आप इस फ़ंक्शन को कितना विश्वसनीय बनाना चाहते हैं। यदि आप जानना चाहते हैं कि आपके पास मौजूद विशेष प्रक्रिया उदाहरण अभी भी चल रहा है और 100% सटीकता के साथ उपलब्ध है तो आप भाग्य से बाहर हैं। कारण यह है कि प्रबंधित प्रक्रिया ऑब्जेक्ट से प्रक्रिया की पहचान करने के केवल 2 तरीके हैं।
पहला प्रोसेस आईडी है। दुर्भाग्य से, प्रक्रिया आईडी अद्वितीय नहीं हैं और इसे पुनर्नवीनीकरण किया जा सकता है। एक मिलान आईडी के लिए प्रक्रिया सूची खोजना केवल आपको बताएगा कि उसी आईडी के साथ एक प्रक्रिया चल रही है, लेकिन जरूरी नहीं कि यह आपकी प्रक्रिया हो।
दूसरा आइटम प्रोसेस हैंडल है। यह ईद के रूप में एक ही समस्या है और इसके साथ काम करने के लिए और अधिक अजीब है।
यदि आप मध्यम स्तर की विश्वसनीयता की तलाश कर रहे हैं तो उसी आईडी की प्रक्रिया के लिए वर्तमान प्रक्रिया सूची की जाँच करना पर्याप्त है।
Process.GetProcesses()
जाने का रास्ता है। लेकिन आपको अपनी प्रक्रिया को खोजने के लिए एक या एक से अधिक विभिन्न मानदंडों का उपयोग करने की आवश्यकता हो सकती है, यह इस बात पर निर्भर करता है कि यह कैसे चल रहा है (यानी एक सेवा या एक सामान्य ऐप के रूप में, चाहे उसका शीर्षक हो या नहीं)।
हो सकता है (शायद) मैं प्रश्न को गलत तरीके से पढ़ रहा हूं, लेकिन क्या आप HasExited संपत्ति की तलाश कर रहे हैं जो आपको बताएगी कि आपकी प्रक्रिया ऑब्जेक्ट द्वारा दर्शाई गई प्रक्रिया बाहर निकल गई है (या तो सामान्य रूप से या नहीं)।
यदि आपके पास UI का संदर्भ लेने वाली प्रक्रिया है, तो आप यह निर्धारित करने के लिए प्रतिसाद गुण का उपयोग कर सकते हैं कि UI वर्तमान में उपयोगकर्ता इनपुट पर प्रतिक्रिया दे रहा है या नहीं।
यदि आप ब्लॉक करना चाहते हैं तो आप EnableRaisingEvents को भी सेट कर सकते हैं और बाहर निकलने की घटना (जो asychronously भेजी जाती है) या WaitForExit () को कॉल कर सकते हैं।
आप जिस प्रक्रिया को चाहते हैं, उसके लिए आप एक बार एक प्रोसेस इंस्टेंस को इंस्टाल कर सकते हैं और उस .NET प्रोसेस ऑब्जेक्ट का उपयोग करके प्रक्रिया को ट्रैक करते रह सकते हैं (यह तब तक ट्रैकिंग करता रहेगा, जब तक आप उस .NET ऑब्जेक्ट को स्पष्ट रूप से बंद नहीं करते, भले ही वह जिस प्रक्रिया को ट्रैक कर रहा हो, उसकी मृत्यु हो गई हो। [यह आपको प्रक्रिया का समय देने में सक्षम होने के लिए सक्षम है, उर्फ एक्ज़िट टाइम आदि]]
उद्धरण : http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx :
जब एक संबद्ध प्रक्रिया बाहर निकलती है (अर्थात, जब इसे सामान्य या असामान्य समाप्ति के माध्यम से ऑपरेशन सिस्टम द्वारा बंद कर दिया जाता है), तो सिस्टम प्रक्रिया के बारे में प्रशासनिक जानकारी संग्रहीत करता है और उस घटक पर वापस लौटता है जिसे WaitForExit कहा जाता था। प्रक्रिया घटक फिर सूचना का उपयोग कर सकता है, जिसमें ExitTime शामिल है, हैंडल से बाहर निकलने की प्रक्रिया का उपयोग करके।
क्योंकि संबद्ध प्रक्रिया से बाहर हो गया है, घटक की हैंडल प्रॉपर्टी अब किसी मौजूदा प्रक्रिया संसाधन की ओर इशारा नहीं करती है। इसके बजाय, हैंडल का उपयोग केवल ऑपरेटिंग सिस्टम की प्रक्रिया संसाधन की जानकारी तक पहुंचने के लिए किया जा सकता है। सिस्टम बाहरी प्रक्रियाओं से हैंडल करने के बारे में जानता है जो प्रक्रिया घटकों द्वारा जारी नहीं की गई है, इसलिए यह ExitTime और हैंडल जानकारी को स्मृति में रखता है जब तक कि प्रक्रिया घटक विशेष रूप से संसाधनों को मुक्त नहीं करता है। इस कारण से, जब भी आप किसी प्रक्रिया उदाहरण के लिए प्रारंभ कॉल करते हैं, तो संबंधित प्रक्रिया समाप्त होने पर कॉल बंद करें और आपको इसके लिए किसी भी प्रशासनिक जानकारी की आवश्यकता नहीं है। पास आउट की गई प्रक्रिया में आवंटित मेमोरी को बंद कर देता है।
मैंने 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 );
यह काम करता है (अब तक)
openApplication.HasExited()
, HasExited कोई फ़ंक्शन नहीं है। सही तरीका होगा openApplication.HasExited
।
प्रक्रिया आईडी द्वारा मौजूदा प्रक्रिया की जाँच के बारे में .Net फ्रेमवर्क से समर्थित एपीआई के बावजूद, वे कार्य बहुत धीमी गति से होते हैं। Process.GetProcesses () या Process.GetProcessById / Name () को चलाने के लिए बड़ी मात्रा में CPU चक्रों का खर्च आता है।
आईडी द्वारा चल रही प्रक्रिया की जांच करने के लिए एक बहुत तेज तरीका देशी एपीआई ओपनप्रोसेस () का उपयोग करना है । यदि रिटर्न हैंडल 0 है, तो प्रक्रिया मौजूद नहीं है। यदि हैंडल 0 से भिन्न है, तो प्रक्रिया चल रही है। अनुमति के कारण हर समय यह विधि 100% काम करेगी इसकी कोई गारंटी नहीं है।
इससे जुड़ी कई समस्याएं हैं, जैसा कि अन्य को आंशिक रूप से पता है:
दूसरों ने जिन संपत्तियों का उल्लेख किया है वे आंतरिक हैं या नहीं, आप अभी भी प्रतिबिंब के माध्यम से उनसे जानकारी प्राप्त कर सकते हैं यदि अनुमति देता है।
var x = obj.GetType().GetProperty("Name", BindingFlags.NonPublic | BindingFlags.Instance);
आप स्नैपशॉट के लिए Win32 कोड पिन कर सकते हैं या आप WMI का उपयोग कर सकते हैं जो धीमा है।
HANDLE CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
एक अन्य विकल्प OpenProcess के लिए होगा / CloseProcess, लेकिन आप अभी भी अपवाद पहले की तरह ही फेंके जाने के साथ एक ही समस्या आने पर होगा।
WMI के लिए - OnNewEvent.Properties ["?"]:
string process = "notepad";
if (Process.GetProcessesByName(process).Length == 0)
{
MessageBox.Show("Working");
}
else
{
MessageBox.Show("Not Working");
}
इसके अलावा, आप हर बार प्रक्रिया की जाँच के लिए एक टाइमर का उपयोग कर सकते हैं
length == 0
प्रदर्शित होना चाहिए Not Working
) लेकिन फिर भी काम हो जाता है।