Respuestas:
Esta es una forma de hacerlo con el nombre:
Process[] pname = Process.GetProcessesByName("notepad");
if (pname.Length == 0)
MessageBox.Show("nothing");
else
MessageBox.Show("run");
Puede repetir todo el proceso para obtener la ID para su posterior manipulación:
Process[] processlist = Process.GetProcesses();
foreach(Process theprocess in processlist){
Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id);
}
if/else
declaraciones de C # que solo tienen una línea de longitud no necesitan tener llaves para indicar la declaración de bloque. Esto también se aplica a foreach
y for
declaraciones. Se reduce al estilo de codificación.
for
. Años de c # .net dev y nunca he visto este estilo. Como dicen, "aprendes algo nuevo todos los días". Gracias por la publicación y la respuesta ..
Esta es la forma más simple que encontré después de usar el reflector. Creé un método de extensión para eso:
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;
}
}
El Process.GetProcessById(processId)
método llama al ProcessManager.IsProcessRunning(processId)
método y lanza ArgumentException
en caso de que el proceso no exista. Por alguna razón, la ProcessManager
clase es interna ...
Solución sincrónica:
void DisplayProcessStatus(Process process)
{
process.Refresh(); // Important
if(process.HasExited)
{
Console.WriteLine("Exited.");
}
else
{
Console.WriteLine("Running.");
}
}
Solución asincrónica:
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 tuvo una muy buena respuesta; sin embargo, no tiene en cuenta una situación en la que el proceso nunca se inició para comenzar.
Aquí hay una versión modificada de lo que publicó.
public static bool IsRunning(this Process process)
{
try {Process.GetProcessById(process.Id);}
catch (InvalidOperationException) { return false; }
catch (ArgumentException){return false;}
return true;
}
Eliminé su ArgumentNullException porque en realidad se supone que es una excepción de referencia nula y el sistema la arroja de todos modos y también tomé en cuenta la situación en la que el proceso nunca se inició o el método close () se usó para cerrar el proceso.
Depende de qué tan confiable desee que sea esta función. Si desea saber si la instancia de proceso particular que tiene todavía se está ejecutando y está disponible con una precisión del 100%, entonces no tiene suerte. La razón es que desde el objeto de proceso administrado solo hay 2 formas de identificar el proceso.
El primero es el Id. De proceso. Desafortunadamente, los identificadores de proceso no son únicos y pueden reciclarse. Buscar en la lista de procesos un Id. Coincidente solo le indicará que hay un proceso con el mismo id en ejecución, pero no es necesariamente su proceso.
El segundo elemento es el controlador de proceso. Sin embargo, tiene el mismo problema que el Id y es más incómodo trabajar con él.
Si está buscando confiabilidad de nivel medio, entonces es suficiente verificar la lista de procesos actual para un proceso de la misma ID.
Process.GetProcesses()
Es el camino a seguir. Pero es posible que necesite usar uno o más criterios diferentes para encontrar su proceso, dependiendo de cómo se esté ejecutando (es decir, como un servicio o una aplicación normal, tenga o no una barra de título).
Tal vez (probablemente) estoy leyendo la pregunta incorrectamente, pero ¿está buscando la propiedad HasExited que le dirá que el proceso representado por su objeto Process ha salido (normalmente o no).
Si el proceso al que tiene una referencia tiene una IU, puede usar la propiedad Respondiendo para determinar si la IU está respondiendo actualmente a la entrada del usuario o no.
También puede establecer EnableRaisingEvents y controlar el evento Exited (que se envía de forma astronómica) o llamar a WaitForExit () si desea bloquear.
Puede crear una instancia de Process una vez para el proceso que desea y seguir rastreando el proceso usando ese objeto de Proceso .NET (seguirá rastreando hasta que llame a Cerrar en ese objeto .NET explícitamente, incluso si el proceso que estaba rastreando ha muerto [Esto es para poder darle tiempo de cierre del proceso, también conocido como ExitTime, etc.])
Citando http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx :
Cuando sale un proceso asociado (es decir, cuando el sistema operativo lo cierra a través de una terminación normal o anormal), el sistema almacena información administrativa sobre el proceso y regresa al componente que había llamado WaitForExit. El componente Proceso puede acceder a la información, que incluye ExitTime, utilizando el controlador para el proceso salido.
Debido a que el proceso asociado ha salido, la propiedad Manejar del componente ya no apunta a un recurso de proceso existente. En cambio, el identificador solo se puede utilizar para acceder a la información del sistema operativo sobre el recurso del proceso. El sistema conoce los manejadores de los procesos salidos que no han sido liberados por los componentes del Proceso, por lo que mantiene la información ExitTime and Handle en la memoria hasta que el componente del Proceso libere específicamente los recursos. Por este motivo, cada vez que llame a Inicio para una instancia de Proceso, llame a Cerrar cuando el proceso asociado haya finalizado y ya no necesite ninguna información administrativa al respecto. Cerrar libera la memoria asignada al proceso salido.
Probé la solución de Coincoin:
antes de procesar algún archivo, lo copio como un archivo temporal y lo abro.
Cuando termino, cierro la aplicación si aún está abierta y elimino el archivo temporal:
solo uso una variable de proceso y la verifico después:
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 );
}
Más tarde cierro la aplicación:
...
openApplication.Refresh();
// close application if it is still open
if ( !openApplication.HasExited() ) {
openApplication.Kill();
}
// delete temporary file
System.IO.File.Delete( fileCache );
Funciona (hasta ahora)
openApplication.HasExited()
, HasExited no es una función. La forma correcta sería openApplication.HasExited
.
A pesar de la API compatible de los marcos .Net con respecto a la verificación del proceso existente por ID de proceso, esas funciones son muy lentas. Cuesta una gran cantidad de ciclos de CPU ejecutar Process.GetProcesses () o Process.GetProcessById / Name ().
Un método mucho más rápido para verificar un proceso en ejecución por ID es usar API OpenProcess () . Si el identificador de retorno es 0, el proceso no existe. Si el identificador es diferente de 0, el proceso se está ejecutando. No hay garantía de que este método funcione al 100% en todo momento debido a un permiso.
Hay muchos problemas asociados con esto, ya que otros parecen haber abordado parcialmente:
Si las propiedades que otros han mencionado son internas o no, aún puede obtener información de ellas a través de la reflexión si el permiso lo permite.
var x = obj.GetType().GetProperty("Name", BindingFlags.NonPublic | BindingFlags.Instance);
Puede pinvokear el código Win32 para Snapshot o puede usar WMI, que es más lento.
HANDLE CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
Otra opción sería OpenProcess / CloseProcess, pero aún se encontrará con los mismos problemas, con las mismas excepciones que antes.
Para WMI - OnNewEvent.Properties ["?"]:
string process = "notepad";
if (Process.GetProcessesByName(process).Length == 0)
{
MessageBox.Show("Working");
}
else
{
MessageBox.Show("Not Working");
}
También puede usar un temporizador para verificar el proceso cada vez
length == 0
debería aparecer Not Working
) pero aún así hace el trabajo.