Запись в консоль другого процесса с использованием API (без перенаправления стандартного ввода) - PullRequest
0 голосов
/ 02 ноября 2018

Я ищу способ записи в консоль другого процесса, используя WinApi, без перенаправления стандартного ввода процесса.

По сути, мое приложение (написанное на C #) является оболочкой для другого консольного приложения.

Это стороннее приложение принимает пользовательские команды в своей консоли. Мое приложение-оболочка должно запустить его и написать такие команды в консоли. Тем не менее, я ограничен в перенаправлении стандартного потока ввода, потому что это вызывает сбой этого стороннего приложения.

Поэтому я ищу решение, использующее WinAPI (или другой способ) для решения этой проблемы.

Вот краткая часть кода (надеюсь, уместно изобразить то, что я пытаюсь сделать):

ProcessStartInfo startInfo = new ProcessStartInfo
{
    FileName = path
    ,Arguments = string.Join(" ", Args)
    ,UseShellExecute = false
    ,CreateNoWindow = true
    ,RedirectStandardOutput = true
    ,RedirectStandardError = true
    //,RedirectStandardInput = true //This leads the process to crash!
};

Process myProcess = new Process
{
    StartInfo = startInfo
};

myProcess.Start();

/*...*/

public void SendInput(string input)
{
    //TODO: see how to send input to process' console   
    int result = SendMessage(myProcess.Handle, 0x000C, 0, input + '\n'); // Not working :(
}

1 Ответ

0 голосов
/ 05 ноября 2018

В конце концов я нашел решение, отправив нажатия клавиш в процесс. Например. Если я хочу написать полную команду, отправьте соответствующий код ключа для каждого символа из командной строки, за которым следует «ENTER».

Код:

    const uint WM_KEYDOWN = 0x100;
    const uint KEY_ENTER = 13;

    [DllImport("user32.dll")]
    public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
    public static extern IntPtr FindWindowByCaption(IntPtr zeroOnly, string lpWindowName);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    static extern short VkKeyScanA(char ch);

    public void SendInput(string input)
    {
        IntPtr windowHandle = FindWindowByCaption(IntPtr.Zero, myProcess.MainWindowTitle);

        foreach(char c in input)
        {
            PostMessage(windowHandle, WM_KEYDOWN, ((IntPtr)VkKeyScanA(c)), IntPtr.Zero);
        }
        PostMessage(windowHandle, WM_KEYDOWN, ((IntPtr)KEY_ENTER), IntPtr.Zero);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...