Pregunta

No sé casi nada sobre linq.

Estoy haciendo esto:

var apps = from app in Process.GetProcesses()
    where app.ProcessName.Contains( "MyAppName" ) && app.MainWindowHandle != IntPtr.Zero
    select app;

Lo que me proporciona todos los procesos en ejecución que coinciden con ese criterio.

Pero no sé cómo conseguir el primero.Los ejemplos que puedo encontrar en la red parecen implicar que tengo que hacer esto.

var matchedApp = (from app in Process.GetProcesses()
    where app.ProcessName.Contains( "MyAppName" ) && app.MainWindowHandle != IntPtr.Zero
    select app).First();

lo que me parece algo feo y también genera una excepción si no hay procesos coincidentes.¿Existe una mejor manera?

ACTUALIZAR

De hecho, estoy tratando de encontrar el primer elemento coincidente y llamar SetForegroundWindow en eso

Se me ocurrió esta solución, que también me parece fea y horrible, pero mejor que la anterior.¿Algunas ideas?

var unused = from app in Process.GetProcesses()
    where app.ProcessName.Contains( "MyAppName" ) && app.MainWindowHandle != IntPtr.Zero
    select SetForegroundWindow( app.MainWindowHandle ); // side-effects in linq-query is technically bad I guess
¿Fue útil?

Solución

@FryHard FirstOrDefault funcionará, pero recuerde que devuelve nulo si no se encuentra ninguno.Este código no está probado pero debería ser similar a lo que desea:

var app = Process.GetProcesses().FirstOrDefault(p => p.ProcessName.Contains("MyAppName") && p.MainWindowHandle != IntPtr.Zero);

if (app == null)
    return;

SetForegroundWindow(app.MainWindowHandle);

Otros consejos

Hacer no usar Count() como dice ICR. Count() iterará a través del IEnumerable para saber cuántos elementos tiene.En este caso, la penalización en el rendimiento puede ser insignificante ya que no hay muchos procesos, pero es un mal hábito.Uso único Count() cuando tu consulta solo esta interesada en el número de resultados. Count casi nunca es una buena idea.

Hay varios problemas con la respuesta de FryHard.Primero, debido a ejecución retrasada, terminará ejecutando la consulta LINQ dos veces, una para obtener el número de resultados y otra para obtener el FirstOrDefault.En segundo lugar, no hay razón alguna para utilizar FirstOrDefault después de comprobar el recuento.Dado que puede devolver nulo, nunca debes usarlo sin verificar si es nulo.O lo haces apps.First().MainWindowHandle o:

var app = apps.FirstOrDefault();

if (app != null)
    SetForegroundWindow(app.MainWindowHandle);

Por eso la mejor solución es la de Mark, sin lugar a dudas.Es la forma más eficiente y estable de utilizar LINQ para conseguir lo que desea.

Suponiendo que en su primer ejemplo las aplicaciones son IEnumerable, podría utilizar las propiedades .Count y .FirstOrDefault para obtener el elemento único que desea pasar a SetForegroundWindow.

var apps = from app in Process.GetProcesses()
where app.ProcessName.Contains( "MyAppName" ) && app.MainWindowHandle != IntPtr.Zero
select app;

if (apps.Count > 0)
{
    SetForegroundWindow(apps.FirstOrDefault().MainWindowHandle );
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top