当程序编译为64位时,WinAPI函数AttachConsole
始终返回true。
首先,我声明了以下函数:
function AttachConsole(dwProcessId: DWORD): Bool; stdcall; external KERNEL32 name 'AttachConsole';
然后我调用我的函数:
if AttachConsole(DWORD(-1)) then
....
当编译为32位应用程序时,此方法工作正常,但当编译为64位应用程序时,它始终返回true。
documentation并未提及对64位应用程序进行特殊处理。
如何复制:
program Project1;
uses
System.Types,
WinApi.windows,
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
function AttachConsole(dwProcessId: DWORD): Bool; stdcall; external KERNEL32 name 'AttachConsole';
begin
if AttachConsole(DWORD(-1)) then
begin
writeLN('Hello world');
Exit;
end;
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
在Win64下运行时,即使从资源管理器运行,AttachConsole
也会重新运行。
答案 0 :(得分:9)
通过documenation链接,dwProcessId [in]
可以采用两种类型的值-目标进程的PID或特殊参数:
ATTACH_PARENT_PROCESS (DWORD)-1
使用当前进程的父级控制台。
此处您使用的是值ATTACH_PARENT_PROCESS
。
在进行64位调试的情况下,IDE似乎正在为64位调试器创建一个控制台,该控制台将调试后的应用程序作为子项承载,因此选择附加到父控制台会成功。
对于32位调试会话,该应用程序作为IDE的子级产生。我们可以猜测这是因为IDE本身是一个32位应用程序,并且可以将64位应用程序必须附加到64位调试器上而直接挂接到32位进程中。
使用流程浏览器,我们可以在IDE中启动调试流程时看到流程层次结构的差异:
在这里我们可以看到64位进程作为调试器内核中的子进程托管,而32位进程则不是。
在AttachConsole(ATTACH_PARENT_PROCESS)
失败的地方,在调试器之外运行(64位)应用程序会产生预期的结果。