【问题标题】:Sending keyboard commands to DOSBOX from C#从 C# 向 DOSBOX 发送键盘命令
【发布时间】:2013-01-23 08:42:04
【问题描述】:

我想向 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 方法的其他参数是 keyboard notification keydown 的代码和 down arrow key 的代码。

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

【问题讨论】:

    标签: c# keyboard-events dosbox


    【解决方案1】:

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

    DOSBOX 是SDL application,因此在 OpenGL 中运行。向 OpenGL 应用程序发送消息一直是 discussed before 并使用 SendInput() method 完成。这显然是 SendKeys 在后台调用的内容,所以我不确定为什么这对我不起作用,但看起来我不是唯一一个。

    This unmaintained library 似乎可以正常工作,或者可以自定义实现like this

    上面堆栈溢出链接中讨论的另一个选项是编写一个 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));
    }
    

    【讨论】:

      【解决方案2】:

      Microsoft 早前就有关于这个主题的 article 以及完整的实施。

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

      控制台应用:

      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");
      

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

      【讨论】:

      • 这看起来更多地与在控制台应用程序中接收消息有关,我想做的只是向我无法修改的应用程序发送消息。
      • @Adam 哦,我明白了。我没有意识到您无法控制控制台应用程序?所以你想要的只是将击键从你的 c# windows 应用程序发送到控制台应用程序?为什么不直接使用System.Windows.Forms.SendKeys.SendWait()
      • 这是我第一次尝试的方法,也不起作用。根据我的研究,它看起来是为了向其他 Windows 窗体应用程序发送消息。我从here 获取了大部分代码
      • 我刚用记事本试了一下,效果很好,但在 DOSBOX 上不行。你用 DOSBOX 试过了吗?
      • 试过你的代码,它确实适用于控制台窗口,但不适用于 DOSBOX,我认为是因为 DOSBOX 是一个 SDL 应用程序。
      猜你喜欢
      • 2011-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-17
      • 2012-03-30
      • 2023-04-05
      • 2016-05-15
      • 1970-01-01
      相关资源
      最近更新 更多