3

我想向 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 方法的其他参数是键盘通知 keydown的代码和向下箭头键的代码。

所以我的问题是,我怎样才能修改我的代码以将按键发送到 DOSBOX,或者有什么不同的方法可以实现这一点?

4

2 回答 2

3

所以我设法让它自己工作,这就是我发现的。

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

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

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

下来.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));
}
于 2013-02-08T11:56:38.647 回答
2

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

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

控制台应用程序:

class Program
{
    static void Main(string[] args)
    {

        ConsoleKeyInfo ki = Console.ReadKey();
        while (ki.KeyChar != 'Z')
        {
            Console.WriteLine(ki.KeyChar);
            ki = Console.ReadKey();
        }
    }
}

Winform 应用程序:

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

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

于 2013-02-07T18:19:53.663 回答