Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 如何从另一个进程获取访问控制台缓冲区?AttachConsole错误\u无效\u参数_Windows_Delphi_Winapi_Console - Fatal编程技术网

Windows 如何从另一个进程获取访问控制台缓冲区?AttachConsole错误\u无效\u参数

Windows 如何从另一个进程获取访问控制台缓冲区?AttachConsole错误\u无效\u参数,windows,delphi,winapi,console,Windows,Delphi,Winapi,Console,我想访问另一个进程控制台的缓冲区(通过AttachConsole),以便调用ReadConsoleOutput等 是一个DOS 16位应用程序。我不能使用管道,因为它不能安全地写入输出(它模拟“windows”。。就像FAR commander,如果你知道我的意思的话) 因此,我应该: 1) 启动应用程序 2) 获取进程id 3) 调用附件控制台(ProcId) 4) 调用GetConsoleScreenBufferInfo获取大小 5) 调用ReadConsoleOutput 问题出现在3:当

我想访问另一个进程控制台的缓冲区(通过AttachConsole),以便调用ReadConsoleOutput等

是一个DOS 16位应用程序。我不能使用管道,因为它不能安全地写入输出(它模拟“windows”。。就像FAR commander,如果你知道我的意思的话)

因此,我应该:

1) 启动应用程序 2) 获取进程id 3) 调用附件控制台(ProcId) 4) 调用GetConsoleScreenBufferInfo获取大小 5) 调用ReadConsoleOutput

问题出现在3:当我调用AttachConsole时,ir返回0,在调用GetLastError后,它报告错误\u无效\u参数87(0x57)

AttachConsole的唯一参数是ProcessId,我已经用ProcessExplorer检查了它是否正确(它实际上是模拟应用程序的ntvdm.exe的PID)

Delphi代码:

function AttachConsole(dwProcessId: DWORD): Cardinal; external kernel32 name 'AttachConsole';

var
  Handle: HWND;

function EnumWindowsProc(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
var
  s: string;
  IsVisible, IsOwned, IsAppWindow: Boolean;
begin
  Result := True;//carry on enumerating

  IsVisible := IsWindowVisible(hwnd);
  if not IsVisible then
    exit;

  IsOwned := GetWindow(hwnd, GW_OWNER)<>0;
  if IsOwned then
    exit;

  IsAppWindow := GetWindowLongPtr(hwnd, GWL_STYLE) and WS_EX_APPWINDOW<>0;
  if not IsAppWindow then
    exit;

  SetLength(s, GetWindowTextLength(hwnd));
  GetWindowText(hwnd, PChar(s), Length(s)+1);
  if AnsiContainsText(s, '????.EXE') then // set windows name to search
    Handle := hwnd;
end;

procedure Test(Strings: TStrings);
var
  ProcessID: Cardinal;
begin
  Handle := 0;
  EnumWindows(@EnumWindowsProc, 0);
  Strings.Add('Handle: ' + IntToStr(Handle));
  if Handle <> 0 then
    SetForegroundWindow(Handle);
  Sleep(100);

  GetWindowThreadProcessId(Handle, @ProcessID);
  Strings.Add('ProcessId: ' + IntToStr(ProcessID));

  if AttachConsole(ProcessId) <> 0 then
    Strings.Add('Ok Attached')
  else
    Strings.Add('Error: ' + IntToStr(GetLastError));
end;

定义应为:

function AttachConsole(dwProcessId: DWORD): BOOL; stdcall; external
kernel32 name 'AttachConsole';
if AttachConsole(ProcessId) then
因此,下面的代码应该是:

function AttachConsole(dwProcessId: DWORD): BOOL; stdcall; external
kernel32 name 'AttachConsole';
if AttachConsole(ProcessId) then

再也帮不了你了。

定义应该是:

function AttachConsole(dwProcessId: DWORD): BOOL; stdcall; external
kernel32 name 'AttachConsole';
if AttachConsole(ProcessId) then
因此,下面的代码应该是:

function AttachConsole(dwProcessId: DWORD): BOOL; stdcall; external
kernel32 name 'AttachConsole';
if AttachConsole(ProcessId) then

无法再为您提供帮助。

尝试将
stdcall
调用约定添加到AttachConsole函数。尝试将
stdcall
调用约定添加到AttachConsole函数。