Yanıtlar:
Bu, adıyla yapmanın bir yoludur:
Process[] pname = Process.GetProcessesByName("notepad");
if (pname.Length == 0)
MessageBox.Show("nothing");
else
MessageBox.Show("run");
Daha sonra işlem yapmak üzere kimliği almak için tüm işlemleri döngüye alabilirsiniz:
Process[] processlist = Process.GetProcesses();
foreach(Process theprocess in processlist){
Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id);
}
if/elseYalnızca bir satır uzunluğundaki C # ifadelerinin blok ifadesini belirtmek için süslü parantezleri olması gerekmez. Bu da geçerlidir foreachve forifadeler. Kodlama stiline kadar kaynar.
for. Yıl c # .net dev ve ben bu tarzı hiç görmedim. Dedikleri gibi, "her gün yeni bir şeyler öğreniyorsun".
Reflektör kullandıktan sonra bulduğum en basit yol bu. Bunun için bir uzantı yöntemi oluşturdum:
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;
}
}
Yöntem, Process.GetProcessById(processId)yöntemi çağırır ProcessManager.IsProcessRunning(processId)ve ArgumentExceptionişlemin olmaması durumunda atar . Nedense ProcessManagersınıf içseldir ...
Senkron çözüm:
void DisplayProcessStatus(Process process)
{
process.Refresh(); // Important
if(process.HasExited)
{
Console.WriteLine("Exited.");
}
else
{
Console.WriteLine("Running.");
}
}
Asenkron çözüm:
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'in hoş bir cevabı vardı; ancak, sürecin hiç başlamamış olduğu bir durumu açıklamaz.
İşte onun yayınladığı değiştirilmiş bir versiyonu.
public static bool IsRunning(this Process process)
{
try {Process.GetProcessById(process.Id);}
catch (InvalidOperationException) { return false; }
catch (ArgumentException){return false;}
return true;
}
Onun aslında null başvuru istisnası olduğunu varsayalım onun ArgumentNullException kaldırıldı ve yine de sistem tarafından atılır ve ben de sürecin asla başlamadı veya close () yöntemini kapatmak için kullanılan durumu açıkladı süreci.
Bu işlevin ne kadar güvenilir olmasını istediğinize bağlıdır. Sahip olduğunuz belirli işlem vakasının hala çalışıp çalışmadığını ve% 100 doğrulukla kullanılabilir olup olmadığını bilmek istiyorsanız, şansınız kalmaz. Bunun nedeni, yönetilen işlem nesnesinden işlemi tanımlamanın yalnızca 2 yolu olmasıdır.
Birincisi İşlem Kimliği. Ne yazık ki, süreç kimlikleri benzersiz değildir ve geri dönüştürülebilir. İşlem listesinde eşleşen bir Kimlik aramak, yalnızca aynı kimliğe sahip bir işlem olduğunu size söyleyecektir, ancak bu sizin işleminiz olmayabilir.
İkinci madde İşlem Tutamağıdır. Id ile aynı sorunu var ve çalışmak daha garip.
Orta düzeyde güvenilirlik arıyorsanız, geçerli işlem listesinin aynı kimliğe sahip bir işlem olup olmadığını kontrol etmek yeterlidir.
Process.GetProcesses()gitmek için bir yoldur. Ancak, nasıl çalıştığına bağlı olarak (yani bir hizmet veya normal bir uygulama olarak, bir başlık çubuğuna sahip olsun ya da olmasın) sürecinizi bulmak için bir veya daha fazla farklı kriter kullanmanız gerekebilir.
Belki (muhtemelen) soruyu yanlış okuyorum, ancak Process nesneniz tarafından temsil edilen işlemin (normalde ya da değil) çıktığını söyleyen HasExited özelliğini mi arıyorsunuz?
Başvurunuzun bir kullanıcı arayüzü varsa, kullanıcı arayüzünün o anda kullanıcı girdisine yanıt verip vermeyeceğini belirlemek için Yanıtlama özelliğini kullanabilirsiniz.
Ayrıca EnableRaisingEvents öğesini ayarlayabilir ve (asenkron olarak gönderilen) Exited olayını işleyebilir veya engellemek istiyorsanız WaitForExit () öğesini çağırabilirsiniz.
İstediğiniz işlem için bir İşlem örneğini bir kez başlatabilir ve bu .NET İşlem nesnesini kullanarak işlemi izlemeye devam edebilirsiniz (izlediği işlem ölmüş olsa bile, bu .NET nesnesini açıkça Kapat'ı çağırıncaya kadar izlemeye devam eder. [bu size işlemin yakın zamanını verebilir, yani ExitTime vb.])
Son teklif http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx :
İlişkili bir işlem çıktığında (yani, işletim sistemi tarafından normal veya anormal bir sonlandırma yoluyla kapatıldığında), sistem işlemle ilgili yönetim bilgilerini depolar ve WaitForExit adlı bileşene geri döner. Process bileşeni daha sonra ExitTime içeren bilgilere erişilen işleme tanıtıcıyı kullanarak erişebilir.
İlişkili işlemden çıkıldığından, bileşenin Handle özelliği artık varolan bir işlem kaynağına işaret etmez. Bunun yerine, tanıtıcı yalnızca işletim sisteminin işlem kaynağı hakkındaki bilgilerine erişmek için kullanılabilir. Sistem, İşlem bileşenleri tarafından yayımlanmamış çıkış işlemlerinin tutamaçlarının farkındadır, bu nedenle İşlem bileşeni özellikle kaynakları serbest bırakana kadar ExitTime ve Handle bilgilerini bellekte tutar. Bu nedenle, bir İşlem örneği için Başlat'ı her aradığınızda, ilişkili işlem sona erdiğinde ve artık bununla ilgili herhangi bir yönetim bilgisine ihtiyacınız olmadığında Kapat'ı çağırın. Kapat, çıkış işlemine ayrılan belleği serbest bırakır.
Coincoin'in çözümünü denedim:
Bir dosyayı işlemeden önce geçici bir dosya olarak kopyalayıp açıyorum.
İşim bittiğinde, uygulamayı hala açıksa kapatıyorum ve geçici dosyayı siliyorum:
Sadece bir İşlem değişkeni kullanıyorum ve daha sonra kontrol ediyorum:
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 );
}
Daha sonra uygulamayı kapatıyorum:
...
openApplication.Refresh();
// close application if it is still open
if ( !openApplication.HasExited() ) {
openApplication.Kill();
}
// delete temporary file
System.IO.File.Delete( fileCache );
Çalışıyor (şimdiye kadar)
openApplication.HasExited(), HasExited bir işlev değildir. Doğru yol olurdu openApplication.HasExited.
.Net çerçevelerinden desteklenen süreçlerin süreç kimliğiyle kontrol edilmesine rağmen, bu işlevler çok yavaştır. Process.GetProcesses () veya Process.GetProcessById / Name () yöntemini çalıştırmak çok miktarda CPU döngüsüne mal olur.
Çalışan bir işlemi kimliğe göre denetlemek için çok daha hızlı bir yöntem, yerel API OpenProcess () kullanmaktır . Dönüş tanıtıcısı 0 ise işlem mevcut değildir. Tanıtıcı 0'dan farklıysa, işlem çalışıyor demektir. Bu yöntemin izin nedeniyle her zaman% 100 çalışacağının garantisi yoktur.
Diğerleri kısmen ele aldığı gibi, bununla ilişkili birçok sorun var:
Diğerlerinin bahsettiği mülkler içsel olsun ya da olmasın, izin verirse yine de yansıma yoluyla onlardan bilgi alabilirsiniz.
var x = obj.GetType().GetProperty("Name", BindingFlags.NonPublic | BindingFlags.Instance);
Anlık Görüntü için Win32 kodunu iğneleyebilir veya daha yavaş olan WMI kullanabilirsiniz .
HANDLE CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
Başka bir seçenek OpenProcess olacaktır / CloseProcess olacaktır, ancak istisnalar daha önce olduğu gibi atılmaya devam edecek.
WMI - OnNewEvent.Properties ["?"] İçin:
string process = "notepad";
if (Process.GetProcessesByName(process).Length == 0)
{
MessageBox.Show("Working");
}
else
{
MessageBox.Show("Not Working");
}
ayrıca her zaman süreci kontrol etmek için bir zamanlayıcı kullanabilirsiniz
length == 0görüntülenmelidir Not Working) ancak yine de işi bitirir.