执行从 C# 到 EuroTruck 的密钥输出不起作用(PostMessage、user32.dll)
Posted
技术标签:
【中文标题】执行从 C# 到 EuroTruck 的密钥输出不起作用(PostMessage、user32.dll)【英文标题】:Performing Key Output from C# to EuroTruck not working (PostMessage, user32.dll) 【发布时间】:2019-08-02 02:49:02 【问题描述】:我正在尝试让我的 C# 脚本输出到 ets2 以便它为我驱动 (wasd)。为了测试,我使用空格键。我已经在 chrome 和记事本中测试了代码,它可以在其中工作并留出空间。有人知道出了什么问题吗?
更新: 我使用键盘模块为 python 编写了一些测试代码,并让它工作。是否可以将“空格”变成我可以从 C# 更改的变量?
Python 代码:
import keyboard, time
time.sleep(5)
keyboard.press_and_release("space")
Spy++ 中的线程和窗口:
我使用以下代码:
public const int WM_KEYDOWN = 0x0100;
const int VK_SPACE = 0x20;
static void Main(string[] args)
System.Threading.Thread.Sleep(2000); // gives user time to switch tabs
IntPtr programloc = WindowHelper.GetForegroundWindow();
// I also tried using (from Spy++) FindWindow("Euro Truck Simulator 2", "prism3d");
if (programloc == IntPtr.Zero) throw new SystemException();
WindowHelper.PostMessage(programloc, WM_KEYDOWN, VK_SPACE, 0);
以及以下模块 WindowHelper(多个 *** 和 docs.microsoft 页面的组合):
class WindowHelper
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern IntPtr FindWindow(
string lpClassName,
string lpWindowName);
[System.Runtime.InteropServices.DllImport("User32.dll")]
public static extern IntPtr FindWindowEx(
IntPtr hwndParent,
IntPtr hwndChildAfter,
string lpszClass,
string lpszWindos);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "GetForegroundWindow")]
public static extern IntPtr GetForegroundWindow();
【问题讨论】:
【参考方案1】:我自己已经找到了一个(临时)修复方法。但是,此修复对性能不是很友好。欢迎大家有更好的建议。
使用我在问题中描述的键盘功能,我制作了一个使用参数的 python 脚本。此 python 脚本由 C# 脚本使用以下代码启动:
static public string run_python(string cmd, string args)
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = @"C:\Users\Stijn\AppData\Local\Programs\Python\Python36\python.exe";
start.Arguments = string.Format("\"0\" \"1\"", cmd,args);
start.UseShellExecute = false;// Do not use OS shell
start.CreateNoWindow = true; // We don't need new window
start.RedirectStandardOutput = true;// Any output, generated by application will be redirected back
start.RedirectStandardError = true; // Any error in standard output will be redirected back (for example exceptions)
using (Process process = Process.Start(start))
using (StreamReader reader = process.StandardOutput)
string stderr = process.StandardError.ReadToEnd(); // Here are the exceptions from our Python script
string result = reader.ReadToEnd(); // Here is the result of StdOut(for example: print "test")
return result + stderr;
python代码包括:
from keyboard import press_and_release
from sys import argv as args
for i in range(len(args)-1):
press_and_release(args[i+1])
使用可在https://pypi.org/project/keyboard/ 找到的键盘模块
【讨论】:
【参考方案2】:您的代码将立即退出。这是故意的吗?在 main 结束时调用 Console.Readline() 以阻止,直到您提供控制台输入。
【讨论】:
我会试试这个,但是网站上显示的代码是一个简化版本,我已经删除了很多不必要的代码。例如,Windows 窗体也会在尝试按空格键后启动。因此,它在尝试按空格键后不会很快终止。以上是关于执行从 C# 到 EuroTruck 的密钥输出不起作用(PostMessage、user32.dll)的主要内容,如果未能解决你的问题,请参考以下文章