Kiedy otrzymuję odwołanie do a System.Diagnostics.Process
, skąd mogę wiedzieć, czy proces jest aktualnie uruchomiony?
155
Oto sposób na zrobienie tego z nazwą:
Process[] pname = Process.GetProcessesByName("notepad");
if (pname.Length == 0)
MessageBox.Show("nothing");
else
MessageBox.Show("run");
Możesz zapętlić cały proces, aby uzyskać identyfikator do późniejszej manipulacji:
Process[] processlist = Process.GetProcesses();
foreach(Process theprocess in processlist){
Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id);
}
if/else
, które mają tylko jeden wiersz długości, nie muszą mieć nawiasów klamrowych, aby wskazać instrukcję blokową. Dotyczy to takżeforeach
ifor
wypowiedzi. Sprowadza się do stylu kodowania.for
informacji. Lata tworzenia c # .net dev i nigdy nie widziałem tego stylu. Jak mówią, „każdego dnia uczysz się czegoś nowego”. Dziękuję za wiadomość i odpowiedź ..To najprostszy sposób, jaki znalazłem po zastosowaniu reflektora. Stworzyłem do tego metodę rozszerzenia:
Process.GetProcessById(processId)
Metoda wywołujeProcessManager.IsProcessRunning(processId)
metodę i rzucaArgumentException
w przypadku, gdy proces nie istnieje. Z jakiegoś powoduProcessManager
zajęcia są wewnętrzne ...źródło
Rozwiązanie synchroniczne:
Rozwiązanie asynchroniczne:
źródło
reshefm miał całkiem niezłą odpowiedź; nie uwzględnia jednak sytuacji, w której proces nigdy się nie rozpoczął.
Oto zmodyfikowana wersja tego, co opublikował.
Usunąłem jego ArgumentNullException, ponieważ w rzeczywistości przypuszcza się, że jest to wyjątek zerowego odwołania, a mimo to jest wyrzucany przez system, a także uwzględniłem sytuację, w której proces nigdy nie został uruchomiony lub metoda close () została użyta do zamknięcia proces.
źródło
Powinien to być jeden wiersz:
źródło
To zależy od tego, jak niezawodna ma być ta funkcja. Jeśli chcesz wiedzieć, czy konkretna instancja procesu, którą posiadasz, nadal działa i jest dostępna ze 100% dokładnością, to nie masz szczęścia. Powodem jest to, że z obiektu zarządzanego procesu istnieją tylko 2 sposoby identyfikacji procesu.
Pierwsza to identyfikator procesu. Niestety, identyfikatory procesów nie są unikalne i można je poddać recyklingowi. Przeszukanie listy procesów pod kątem pasującego identyfikatora pokaże tylko, że działa proces o tym samym identyfikatorze, ale niekoniecznie jest to Twój proces.
Drugą pozycją jest uchwyt procesu. Ma ten sam problem co Id i jest trudniejszy w obsłudze.
Jeśli szukasz niezawodności na średnim poziomie, wystarczy sprawdzić bieżącą listę procesów pod kątem procesu o tym samym identyfikatorze.
źródło
Process.GetProcesses()
jest droga do zrobienia. Jednak może być konieczne użycie jednego lub więcej różnych kryteriów, aby znaleźć proces, w zależności od tego, jak działa (np. Jako usługa lub zwykła aplikacja, niezależnie od tego, czy ma pasek tytułu, czy nie).źródło
Może (prawdopodobnie) źle czytam pytanie, ale czy szukasz właściwości HasExited, która powie Ci, że proces reprezentowany przez obiekt Process zakończył się (normalnie lub nie).
Jeśli proces, do którego się odwołujesz, ma interfejs użytkownika, możesz użyć właściwości Responding, aby określić, czy interfejs użytkownika aktualnie odpowiada na dane wejściowe użytkownika, czy nie.
Możesz także ustawić EnableRaisingEvents i obsłużyć zdarzenie Exited (które jest wysyłane asychronicznie) lub wywołać WaitForExit (), jeśli chcesz zablokować.
źródło
Możesz utworzyć instancję Process raz dla żądanego procesu i kontynuować śledzenie tego procesu za pomocą tego obiektu .NET Process (będzie on śledził aż do jawnego wywołania Close na tym obiekcie .NET, nawet jeśli śledzony proces nie działa [to ma być w stanie podać czas zakończenia procesu, inaczej ExitTime itp.])
Cytując http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx :
źródło
Wypróbowałem rozwiązanie Coincoin:
przed przetworzeniem jakiegoś pliku kopiuję go jako plik tymczasowy i otwieram.
Kiedy skończę, zamykam aplikację, jeśli jest nadal otwarta, i usuwam plik tymczasowy:
po prostu używam zmiennej procesowej i sprawdzam ją później:
Później zamykam aplikację:
Działa (na razie)
źródło
openApplication.HasExited()
, HasExited nie jest funkcją. Właściwy sposób byłbyopenApplication.HasExited
.Pomimo obsługiwanego API z platform .Net w zakresie sprawdzania istniejącego procesu według identyfikatora procesu, funkcje te działają bardzo wolno. Uruchamianie Process.GetProcesses () lub Process.GetProcessById / Name () kosztuje ogromną liczbę cykli procesora.
Znacznie szybszą metodą sprawdzenia działającego procesu według identyfikatora jest użycie natywnego API OpenProcess () . Jeśli uchwyt zwrotny ma wartość 0, proces nie istnieje. Jeśli uchwyt jest inny niż 0, proces jest uruchomiony. Nie ma gwarancji, że ta metoda będzie działać w 100% przez cały czas ze względu na pozwolenie.
źródło
Jest z tym wiele problemów, które wydawały się częściowo rozwiązać inne:
Niezależnie od tego, czy właściwości, o których wspominali inni, są wewnętrzne, czy nie, nadal możesz uzyskać od nich informacje poprzez refleksję, jeśli pozwolenie na to pozwala.
Możesz przypiąć kod Win32 do Snapshot lub możesz użyć wolniejszego WMI .
Inną opcją byłoby OpenProcess / CloseProcess, ale nadal będziesz mieć te same problemy z wyjątkami, które są wyrzucane tak samo jak wcześniej.
WMI - OnNewEvent.Properties ["?"]:
źródło
możesz również użyć timera do sprawdzania procesu za każdym razem
źródło
length == 0
powinien zostać wyświetlonyNot Working
), ale nadal działa.