如何查找和使用进程 ID 将击键发送到 C# 中的 Excel 应用程序

本文关键字:应用程序 Excel 中的 ID 查找 何查找 进程 | 更新日期: 2023-09-27 17:57:01

通过过滤父进程 ID 号来标识进程,当找到正确的进程时,应该收到击键。此应用程序是一个 Excel 工作簿。宏在此应用程序内运行这需要击键。宏的提供程序无法更改此行为。

宏完成时显示的此用户窗体由于其手动输入要求而禁止自动化。

我尝试了几种不同的方法来发送返回密钥,但它们都失败了。最有希望的如下:

[DllImport("User32.dll")]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll")]
static extern int SetForegroundWindow(IntPtr hWnd);
//...then at the bottom of my script
//p is the Excel process selected from a bunch of Excel workbooks
IntPtr ptrFF = p.Handle;
SetForegroundWindow(ptrFF);
SendKeys.Send("{w 3}");          //<- it falls over at this stage            

错误消息是:

"SendKeys 无法在此应用程序内运行,因为该应用程序不是处理视窗消息。 更改应用程序以处理消息,或使用 SendKeys.SendWait 方法。

如果我使用

SendKeys.SendWait("{w 3}"); 

命令,然后似乎没问题,但击键不知何故没有到达其所需的目的地。

您是否知道如何通过发送键或其他方式找到Excel宏解决此问题的方法?

如何查找和使用进程 ID 将击键发送到 C# 中的 Excel 应用程序

几乎适用于每个窗口(除了一些 Java 窗口)+ 窗口不必成为焦点:

这里还有一个有用的虚拟键代码列表

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll")]
        static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
        private void button1_Click(object sender, EventArgs e)
        {
            const int WM_SYSKEYDOWN = 0x0104;
            const int VK_SPACE = 0x20;
            IntPtr WindowToFind = FindWindow(null, "WINDOW NAME");
            PostMessage(WindowToFind, WM_SYSKEYDOWN, VK_SPACE, 0);
        }

此解决方案的唯一缺陷是它不会将击键发送到Excel用户窗体。这是合资企业的最终目标。

事实证明,解决方案相当简单。这

IntPtr ptrFF = p.Handle;

必须更改为

IntPtr ptrFF = p.MainWindowHandle

虽然我不太确定为什么这解决了我的问题,但它显然适用于记事本和 Excel,所以它似乎是一个解决方案。