了解编程如果一个过程,要求用户输入(Find out programmatically if a p

2019-07-17 15:02发布

我如何编程(C#中)确定,如果另一个外国申请(本机,JAVA,.NET或任何...)目前要求苛刻的用户输入? 这能在托管代码完全做了什么?

我正在寻找的是执行:

static Boolean IsWaitingForUserInput(String processName)
{
    ???
}

通过要求用户输入我的意思是,当一个应用程序要求用户输入一些数据或退出的错误消息(模式对话框),并不能再执行正常任务。 正在等待用户绘制的东西绘图应用程序并不意味着这里。

PS:经过修改,以反映在底部的意见,并做出更清楚的关注,一些意见和答案可能不是100%,问题是一致的。 评价答案和言论时考虑到这一点。

Answer 1:

这一般是不可能的。 就拿常见的一种应用,字处理器。 如今将在后台运行spellchecks,它会定期自动保存您的文档,等等。 然而,从用户的角度来看,它在等待输入所有的时间。

另一种常见的情况是一个幻灯片浏览器。 在任何时刻,你可以按一个键来前进的幻灯片。 然而,典型的用户不会认为这是“等待输入”。

概括地说:“等待输入”是一种主观状态,因此不能以编程方式来确定。



Answer 2:

你喜欢这个?

我工作了,似乎工作的解决方案,请通知我在出现问题时使用这个代码,所以我也收获了改进的好处。 它为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;
        }
    }
}


Answer 3:

如果我理解你很好,你可以尝试枚举该进程的线程,并检查他们的状态。 Windows任务管理器做类似的事情。 然而,这将需要Win32函数 - 等等Thread32First和Thread32Next - 但你可以通过在C#中最简单的使用的P / Invoke的实现这一点:

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

(精确签名可能不同)。

编辑:好的,也有在.NET库相应的功能。



Answer 4:

如果可能,改写其他代码是一个并行输入处理器(类似算法并发web服务器):

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

当然,你仍然可以有你的功能:

static Boolean IsWaitingForUserInput(String processName) {
    return true;
}


文章来源: Find out programmatically if a process is demanding user input