向无窗口命令行进程发送命令(从c#应用程序开始)

本文关键字:应用程序 开始 命令 窗口 命令行 进程 | 更新日期: 2023-09-27 18:18:55

我有一个命令行应用程序启动并做一些工作。在此期间,它监听击键(s => show status)。它不是你按's'和-这是一种反应的类型,只要按下键,状态显示。

现在我正试图通过发送按键从一个花哨的GUI应用程序"控制"命令行应用程序。我尝试过更传统的方法,按照过程标准编写,但似乎根本没有效果。此外,因为实际的进程没有窗口(它开始与CreateNoWindow=true)我不能尝试Win32 API发送击键到窗口。

还有别的方法吗?

向无窗口命令行进程发送命令(从c#应用程序开始)

花哨的控制台应用程序有问题。

它们倾向于直接读取键盘输入,而不是通过stdin。他们也倾向于直接控制他们的控制台,而不是通过标准输出。

我敢说,没有办法以编程方式控制这些应用程序。如果你真的真的需要,我会探索像AutoHotKey这样的东西来控制私人桌面上的应用程序(AHK使用虚拟键盘/鼠标驱动程序)。我不确定你将如何从主机上读取结果;它可能可以创建一个中间控制台应用程序,由你的程序启动(在私有桌面)并启动目标应用程序。然后,中间应用程序将与目标应用程序共享其控制台,并使用低级I/O来检测更改。

或者你可以使用Detours来改变目标应用程序

好了,我似乎找到了我自己问题的答案。这是一个真正的"拼凑在一起"的解决方案,但它是有效的——对于我正在构建的应用程序的所有意图和目的来说,这无关紧要。

我使用了两个WinAPI函数

static extern bool ShowWindow(IntPtr WindowHandle, int nCmdShow);
static extern bool SetForegroundWindow(IntPtr WindowHandle);

第一个可以通过将nCmdShow分别更改为1和0来显示/隐藏窗口。另一个将窗口(由WindowHandle决定)放在前面。将这两者结合在一起,我便能够通过编程将控制台窗口带到前面,执行简单的SendKeys.Send();操作,然后再次隐藏。

// Use a WIN API command to bring the command line to front
SetForegroundWindow(workerProcess.MainWindowHandle);
// Send a keystore to re-display the STATUS of the worker
SendKeys.Send("s");
// Hide the window again.
ShowWindow(workerProcess.MainWindowHandle, 0); 

现在,这是一个真正的拼凑工作,但它完成了工作。一个潜在的陷阱是,如果用户正在使用计算机做其他事情,并且在窗口处于活动状态时使用"q"来锁定10000000分之一的时间,它将退出工作程序。但这款应用程序的目的是在专用机器上使用,这些机器很可能甚至没有显示器、键盘或鼠标,所以这不会是一个问题。

感谢所有回答的人,因为你们这样或那样,引导我走向正确的解决方案。

我发现了一种更好的方法来完成该功能,而不会同时导致用户输入和窗口切换问题的理论风险。

技巧是使用WinAPI的PostMessage函数来发送KeyDown(或KeyUp)消息给做同样事情的进程。不需要将进程窗口放在前面,然后立即隐藏它!

我正在发送key-down命令,键'S'作为参数:

        // 0x0100 - VM_KEYDOWN
        // 0x0101 - VM_KEYUP
        // 0x53 - S-key
        PostMessage(workerProcess.MainWindowHandle, 0x0100, 0x53, 0);
        PostMessage(workerProcess.MainWindowHandle, 0x0101, 0x53, 0);