Вопрос по process, c# – Получить состояние окна другого процесса

10

Как я могу получить состояние окна (maximized, minimized) другого процесса, который запущен?

Я пытался использовать это:

Process[] procs = Process.GetProcesses();

        foreach (Process proc in procs)
        {

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

            }
        }

Но если процессMaximized или жеMinimizedкогда-нибудь вернетсяNormal.

Как это исправить?

Ваш Ответ

4   ответа
7

что неверно. Он не отражает стиль окна времени выполнения целевого процесса. Это просто информация о запуске, которую вы можете установить, и затем она может быть передана процессу при запуске.

Подпись C #:

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

Вам нужно использовать p / invoke и вызвать GetWindowLong (hWnd, GWL_STYLE) и передать proc.MainWindowHandle в качестве параметра hWnd.

Вы можете проверить, свернуто ли окно / развернуто, сделав что-то вроде:

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
}

NOTE: Значения для флагов (WS_MINIMIZE и т. Д.) Можно найти на этой странице:http://www.pinvoke.net/default.aspx/user32.getwindowlong

Спасибо Какаши за указание на ошибку в тестировании результата.

Не забывайте, что C # .NET принимает только логические выражения в операторах if / for / while. Если вы хотите проверитьWS_MAXIMIZE нарезанное значение отstyle само по себе, используя& ты должен сделать(style & WS_MAXIMIZE) == WS_MAXIMIZE.
А также необходимо() или вы получитеOperator '&' cannot be applied to operands of type 'int' and 'bool'
Правда. Обновленный ответ.
@marceln: увидеть эту картинку:thoosje.com/Images/optimizer-screenshot-1.jpg как называется это состояние окна? Jack
Может быть, я должен на самом деле проверить свои вещи :). Спасибо!
2

вызвав WinAPI IsIconic () / IsZoomed () следующим образом:

    [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);
    }

Определение enum ShowWindowCommands и другие функции были взяты из www.PInvoke.net

0

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)"
}
Но это будет работать только на Windows 7 и выше.
22

яния другого окна. Вот пример кода:

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,
}

Определение предоставлено pinvoke.net.

В моем случае,showCmd всегда является исходным значением и остается неизменным, даже еслиShowWindow(showCmd != 1) называется,GetWindowPlacement все еще возвращаетсяshowCmd = 1 вWINDOWPLACEMENT состав. Так буквально ли это в тот момент, когда окно «помещено»?
Не забудьте добавить ссылку наSystem.Drawing

Похожие вопросы