Узнайте программно, если процесс требует ввод данных пользователем

Вероятно, для того же, логичного, который делает это не ошибкой:

public class X
{
    public static void foo()
    {
    }

    public void bar()
    {
        foo(); // no need to do X.foo();
    }
}
5
задан jdehaan 18 September 2009 в 22:14
поделиться

4 ответа

Это вообще невозможно. Возьмем, к примеру, обычное приложение - текстовый процессор. В настоящее время он будет запускать проверку орфографии в фоновом режиме, он периодически автоматически сохраняет ваш документ и т.д. Тем не менее, с точки зрения пользователей, он все время ждет ввода.

Другой распространенный случай - программа просмотра слайд-шоу. В любой момент времени вы можете нажать клавишу, чтобы продвинуть слайд. Тем не менее, ваш обычный пользователь не будет рассматривать это как «ожидание ввода».

Подводя итог: «ожидание ввода» является субъективным состоянием и поэтому не может быть определено программно.

9
ответ дан 13 December 2019 в 05:39
поделиться

Как вам это нравится?

Я разработал решение, которое, похоже, работает, пожалуйста, сообщите мне в случае проблем с этим кодом, чтобы я также получил преимущества от улучшений. Насколько я тестировал, он работает в Excel. Единственная проблема, которая мне не нравится, - это то, что мне приходилось использовать неуправляемые вызовы. Он также обрабатывает случай, когда приложение основано на диалоговом окне, например, для MFC, производном от CDialog.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics;

namespace Util
{
    public class ModalChecker
    {
        public static Boolean IsWaitingForUserInput(String processName)
        {
            Process[] processes = Process.GetProcessesByName(processName);
            if (processes.Length == 0)
                throw new Exception("No process found matching the search criteria");
            if (processes.Length > 1)
                throw new Exception("More than one process found matching the search criteria");
            // for thread safety
            ModalChecker checker = new ModalChecker(processes[0]);
            return checker.WaitingForUserInput;
        }

        #region Native Windows Stuff
        private const int WS_EX_DLGMODALFRAME = 0x00000001;
        private const int GWL_EXSTYLE = (-20);
        private delegate int EnumWindowsProc(IntPtr hWnd, int lParam);
        [DllImport("user32")]
        private extern static int EnumWindows(EnumWindowsProc lpEnumFunc, int lParam);
        [DllImport("user32", CharSet = CharSet.Auto)]
        private extern static uint GetWindowLong(IntPtr hWnd, int nIndex);
        [DllImport("user32")]
        private extern static uint GetWindowThreadProcessId(IntPtr hWnd, out IntPtr lpdwProcessId);
        #endregion

        // The process we want the info from
        private Process _process;
        private Boolean _waiting;

        private ModalChecker(Process process)
        {
            _process = process;
            _waiting = false; //default
        }

        private Boolean WaitingForUserInput
        {
            get
            {
                EnumWindows(new EnumWindowsProc(this.WindowEnum), 0);
                return _waiting;
            }
        }

        private int WindowEnum(IntPtr hWnd, int lParam)
        {
            if (hWnd == _process.MainWindowHandle)
                return 1;
            IntPtr processId;
            GetWindowThreadProcessId(hWnd, out processId);
            if (processId.ToInt32() != _process.Id)
                return 1;
            uint style = GetWindowLong(hWnd, GWL_EXSTYLE);
            if ((style & WS_EX_DLGMODALFRAME) != 0)
            {
                _waiting = true;
                return 0; // stop searching further
            }
            return 1;
        }
    }
}
3
ответ дан 13 December 2019 в 05:39
поделиться

Если я вас хорошо понимаю, вы можете попробовать перечислить потоки процесса и проверить их состояние. Диспетчер задач Windows делает нечто подобное. Однако для этого потребуются функции Win32, среди которых Thread32First и Thread32Next, но вы можете добиться этого с помощью простейшего использования P / Invoke в C #:

    [DllImport("Executor.dll")]
    public static extern bool Thread32First(IntPtr handle, IntPtr threadEntry32);

(Точная подпись может отличаться).

EDIT: Хорошо, есть соответствующие функции в библиотеке .NET.

0
ответ дан 13 December 2019 в 05:39
поделиться

Если возможно, перепишите другой код, чтобы он был процессором одновременного ввода (аналогично алгоритму для параллельного веб-сервера):

Wait for input
Fork process
  Parent: Repeat
  Child: (Worker) handle input

Конечно, у вас все еще может быть ваша функция:

static Boolean IsWaitingForUserInput(String processName) {
    return true;
}
0
ответ дан 13 December 2019 в 05:39
поделиться
Другие вопросы по тегам:

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