Выполнение вывода ключа из C # в EuroTruck не работает (PostMessage, user32.dll) - PullRequest
0 голосов
/ 11 марта 2019

Я пытаюсь заставить мой сценарий C # выводить на ets2, чтобы он работал для меня (wasd).Для тестирования я использую пробел.Я проверил код в Chrome и блокноте, где он работает и ставит пробел.Кто-нибудь знает, что идет не так?

Обновление: я написал немного тестового кода для python, используя модуль клавиатуры, и получил его на работу.Можно ли превратить «пробел» в переменную, которую я могу изменить из C #?

Код Python:

import keyboard, time
time.sleep(5)
keyboard.press_and_release("space")

Потоки и Windows в Spy ++:

enter image description here enter image description here

Я использую следующий код:

    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 (комбинация нескольких Stackoverflow иdocs.microsoft pages):

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();
}

Ответы [ 2 ]

0 голосов
/ 11 марта 2019

Я смог найти (временное) исправление самостоятельно. Однако это исправление не очень благоприятно для производительности. Приветствуются все, у кого есть лучшие предложения.

Используя функцию клавиатуры, которую я описал в своем вопросе, я создал скрипт на 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/

0 голосов
/ 11 марта 2019

Ваш код выходит немедленно. Это намеренно? Выполните вызов Console.Readline () в конце основного блока, чтобы заблокировать его, пока вы не введете консольный ввод.

...