从C#向DOSBOX发送键盘命令

本文关键字:键盘 命令 DOSBOX | 更新日期: 2023-09-27 17:58:17

我想向DOSBOX发送一个键盘命令(向下箭头),然后在C#中执行一些处理代码,然后循环。我的目标是使DOS程序的运行自动化。

我已经成功地在记事本和Windows资源管理器上工作的代码,但不会在DOSBOX上工作。

这是我的(简化)代码:

[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
static void Main(string[] args)
{
    Console.ReadKey();
    System.Threading.Thread.Sleep(2000); //to give me time to set focus to the other window
    SendMessage(new IntPtr(0x001301CE), 0x0100, new IntPtr(0x28), new IntPtr(0));
}

我使用WinSpy++获得了窗口的句柄,DOSBOX只有一个窗口,没有子窗口,这个过程适用于记事本和资源管理器。我发送给SendMessage方法的其他参数是键盘通知键down的代码和向下箭头键的代码。

所以我的问题是,我如何修改我的代码以将按键发送到DOSBOX,或者有其他方法可以实现这一点吗?

从C#向DOSBOX发送键盘命令

所以我自己设法让它工作起来,以下是我的发现。

DOSBOX是一个SDL应用程序,因此在OpenGL中运行。向OpenGL应用程序发送消息之前已经讨论过,并且是使用SendInput()方法完成的。这显然是SendKeys在幕后所说的,所以我不确定为什么这对我不起作用,但看起来我不是唯一一个。

这个未维护的库似乎工作得很好,或者可以像这样完成自定义实现。

上面堆栈溢出链接中讨论的另一个选项是编写一个C或C++库,并通过C#应用程序调用它。这就是我最终要做的,这是代码。

Down.h

extern "C" __declspec(dllexport) void PressDownKey();

下行.cpp

#include <Windows.h>
#include "Down.h"
extern "C" __declspec(dllexport) void PressDownKey()
{
    KEYBDINPUT KeybdInput;
    ZeroMemory(&KeybdInput, sizeof(KeybdInput));
    KeybdInput.wVk = VK_DOWN;
    KeybdInput.dwExtraInfo = GetMessageExtraInfo();
    INPUT InputStruct;
    ZeroMemory(&InputStruct, sizeof(InputStruct));
    InputStruct.ki = KeybdInput;
    InputStruct.type = 1;
    int A = SendInput(1,&InputStruct,sizeof(INPUT));
    Sleep(10);
    ZeroMemory(&KeybdInput, sizeof(KeybdInput));
    KeybdInput.wVk = VK_DOWN;
    KeybdInput.dwFlags = KEYEVENTF_KEYUP;
    KeybdInput.dwExtraInfo = GetMessageExtraInfo();
    ZeroMemory(&InputStruct, sizeof(InputStruct));
    InputStruct.ki = KeybdInput;
    InputStruct.type = 1;
    A = SendInput(1,&InputStruct,sizeof(INPUT));
}

Microsoft有一篇关于这个主题的文章,以及完整的实现。

编辑:评论中的每个对话-这是代码。

控制台应用程序:

class Program
{
    static void Main(string[] args)
    {
        ConsoleKeyInfo ki = Console.ReadKey();
        while (ki.KeyChar != 'Z')
        {
            Console.WriteLine(ki.KeyChar);
            ki = Console.ReadKey();
        }
    }
}

Winforms应用程序:

SendKeys.SendWait("A");
Thread.Sleep(2000);
SendKeys.SendWait("Z");

您可以在控制台应用程序上看到输出,这意味着它正在接收命令。