Теперь в Windows CONHOST «скрыт» за интерфейсом командной строки, таким как cmd.exe или PowerShell.exe. Я нашел несколько упоминаний об использовании CONHOST, но это связано с грубыми методами, такими как [SendKeys], которые не очень надежны, или потоковой передачей контента из файла.
Однако, поскольку Windows 10, в квартале появился новенький. А именно ConPTY, который поддерживает удаленное взаимодействие с консолью.
Мне удалось раздобыть некоторый пример кода, но он продолжает давать сбой в части InteropService в четвертом разделе ниже. ..
И я не говорю на C# :/
Это не очень «просто», но, с другой стороны, очень интересно.< /p>
1. Определите функции псевдоконсоли
Код: Выделить всё
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class PseudoConsole
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreatePseudoConsole(COORD size, IntPtr hInput, IntPtr hOutput, uint dwFlags, out IntPtr phPC);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ClosePseudoConsole(IntPtr hPC);
[StructLayout(LayoutKind.Sequential)]
public struct COORD
{
public short X;
public short Y;
}
}
"@
Код: Выделить всё
$coord = New-Object PseudoConsole+COORD
$coord.X = 80
$coord.Y = 25
$inputPipe = [System.IO.Pipes.AnonymousPipeServerStream]::new([System.IO.Pipes.PipeDirection]::In)
$outputPipe = [System.IO.Pipes.AnonymousPipeServerStream]::new([System.IO.Pipes.PipeDirection]::Out)
$hPC = [IntPtr]::Zero
[PseudoConsole]::CreatePseudoConsole($coord, $inputPipe.SafePipeHandle.DangerousGetHandle(), $outputPipe.SafePipeHandle.DangerousGetHandle(), 0, [ref]$hPC)
Код: Выделить всё
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class ProcessHelper
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CreateProcess(
string lpApplicationName,
string lpCommandLine,
IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes,
bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory,
[In] ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
[StructLayout(LayoutKind.Sequential)]
public struct STARTUPINFO
{
public uint cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public ushort wShowWindow;
public ushort cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
public struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public uint dwProcessId;
public uint dwThreadId;
}
}
"@
Код: Выделить всё
$si = New-Object ProcessHelper+STARTUPINFO
$pi = New-Object ProcessHelper+PROCESS_INFORMATION
$si.cb = [System.Runtime.InteropServices.Marshal]::SizeOf([ProcessHelper+STARTUPINFO])
$si.hStdInput = $inputPipe.SafePipeHandle.DangerousGetHandle()
$si.hStdOutput = $outputPipe.SafePipeHandle.DangerousGetHandle()
$si.hStdError = $outputPipe.SafePipeHandle.DangerousGetHandle()
$si.dwFlags = 0x00000100 # STARTF_USESTDHANDLES
[ProcessHelper]::CreateProcess(
$null,
"cmd.exe",
[IntPtr]::Zero,
[IntPtr]::Zero,
$true,
0,
[IntPtr]::Zero,
$null,
[ref]$si,
[ref]$pi
)
Исключением, вызывающим "SizeOf" с аргументом(ами) "1" : «Тип 'System.RuntimeType' не может быть маршалирован как неуправляемая структура; невозможно вычислить значимый размер или смещение».
В строке:1 char:1
$ si.cb = [System.Runtime.InteropServices.Marshal]::SizeOf([ProcessHel ...
Код: Выделить всё
CategoryInfo : NotSpecified: (:) [], MethodInvocationException
FullyQualifiedErrorId : ArgumentException
Подробнее здесь: https://stackoverflow.com/questions/790 ... shell-v5-1
Мобильная версия