2012-06-16 7 views
8

¿Cómo obtengo el estado de ventana (maximized, minimized) de otro proceso que se está ejecutando?Obtiene el estado de ventana de otro proceso

lo hubiera intentado mediante el uso de esto:

Process[] procs = Process.GetProcesses(); 

     foreach (Process proc in procs) 
     { 

      if (proc.ProcessName == "notepad") 
      { 
       MessageBox.Show(proc.StartInfo.WindowStyle.ToString()); 

      } 
     } 

Pero si el proceso es Maximized o Minimized, se vuelve siempre Normal.

¿Cómo solucionar esto?

Respuesta

17

Deberá usar Win32 a través de P/Invoke para verificar el estado de otra ventana. Aquí hay algunos ejemplos de código:

static void Main(string[] args) 
{ 
    Process[] procs = Process.GetProcesses(); 

    foreach (Process proc in procs) 
    { 
     if (proc.ProcessName == "notepad") 
     { 
      var placement = GetPlacement(proc.MainWindowHandle); 
      MessageBox.Show(placement.showCmd.ToString()); 
     } 
    } 
} 

private static WINDOWPLACEMENT GetPlacement(IntPtr hwnd) 
{ 
    WINDOWPLACEMENT placement = new WINDOWPLACEMENT(); 
    placement.length = Marshal.SizeOf(placement); 
    GetWindowPlacement(hwnd, ref placement); 
    return placement; 
} 

[DllImport("user32.dll", SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
internal static extern bool GetWindowPlacement(
    IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); 

[Serializable] 
[StructLayout(LayoutKind.Sequential)] 
internal struct WINDOWPLACEMENT 
{ 
    public int length; 
    public int flags; 
    public ShowWindowCommands showCmd; 
    public System.Drawing.Point ptMinPosition; 
    public System.Drawing.Point ptMaxPosition; 
    public System.Drawing.Rectangle rcNormalPosition; 
} 

internal enum ShowWindowCommands : int 
{ 
    Hide = 0, 
    Normal = 1, 
    Minimized = 2, 
    Maximized = 3, 
} 

Definición cortesía de pinvoke.net.

+0

En mi caso, 'showCmd' es siempre el valor original, y permanece igual, incluso si se llama' ShowWindow (showCmd! = 1) ',' GetWindowPlacement' todavía devuelve 'showCmd = 1' en la estructura' WINDOWPLACEMENT'. Entonces, ¿es literalmente el momento en que la ventana está "colocada"? –

+0

Recuerde agregar la referencia a 'System.Drawing' – LazerSharks

6

Está utilizando proc.StartInfo, que es incorrecto. No refleja el estilo de ventana de tiempo de ejecución del proceso de destino. Es solo información de inicio que puede establecer y luego puede pasarse al proceso cuando se inicia.

El C# firma es:

[DllImport("user32.dll", SetLastError=true)] 
static extern int GetWindowLong(IntPtr hWnd, int nIndex); 

Es necesario utilizar p/invocar y llamar GetWindowLong (CVent, GWL_STYLE), y pasar proc.MainWindowHandle como el parámetro hWnd.

Puede comprobar si la ventana está minimizada/maximizada haciendo algo como:

int style = GetWindowLong(proc.MainWindowHandle, GWL_STYLE); 
if((style & WS_MAXIMIZE) == WS_MAXIMIZE) 
{ 
    //It's maximized 
} 
else if((style & WS_MINIMIZE) == WS_MINIMIZE) 
{ 
    //It's minimized 
} 

NOTA: Los valores de las banderas (WS_MINIMIZE, etc.), se pueden encontrar en esta página: http://www.pinvoke.net/default.aspx/user32.getwindowlong

Gracias a Kakashi por señalar nuestro error al probar el resultado.

+1

no se olvide de que C# .NET acepta expresiones booleanas solamente en el caso de/para/tiempo-declaraciones. Si desea comprobar 'WS_MAXIMIZE' el valor en corte de' style' es él mismo, al usar '&' debe hacer '(style & WS_MAXIMIZE) == WS_MAXIMIZE'. – Kakashi

+0

cierto. Respuesta actualizada –

+1

Y también es necesario '()' o obtendrá 'Operator '&' no se puede aplicar a operandos de tipo 'int' y 'bool'' – Kakashi

2

dos estados de ventana (maximizada/minimizada) puede ser obtenido llamando WinAPI IsIconic()/IsZoomed() así:

[DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    public static extern bool IsIconic(IntPtr hWnd); 

    [DllImport("user32.dll")] 
    public static extern bool ShowWindowAsync(IntPtr hWnd, ShowWindowCommands cmdShow); 

    if (IsIconic(_helpWindow.MainWindowHandle)) { 
     ShowWindowAsync(_helpWindow.MainWindowHandle, ShowWindowCommands.SW_RESTORE); 
    } 

Definición de ShowWindowCommands ENUM y otras funciones se tomaron de www.PInvoke.net

0

en Windows PowerShell se puede hacer esto mediante el siguiente código:

Add-Type -AssemblyName UIAutomationClient 
$prList = Get-Process -Name "<ProcessNamesWhichHaveWindow>" 
$prList | % { 
    $ae = [System.Windows.Automation.AutomationElement]::FromHandle($_.MainWindowHandle) 
    $wp = $ae.GetCurrentPattern([System.Windows.Automation.WindowPatternIdentifiers]::Pattern) 
    echo "Window title: $($_.MainWindowTitle)" 
    echo "Window visual state: $($wp.Current.WindowVisualState)" 
} 
+0

Pero esto funcionará solo en Windows 7 y superior. – Ladislav

Cuestiones relacionadas