【问题标题】:How to pass a pointer to a list of handles to the UpdateProcThreadAttribute function如何将指向句柄列表的指针传递给 UpdateProcThreadAttribute 函数
【发布时间】:2020-03-06 11:57:09
【问题描述】:

我有一个产生多个 CreateProcess 线程的应用程序,并且我成功地将 stdout 和 stderr 输出重定向到每个文本文件。

但是,我发现了 stdout/strderr 句柄由所有此类线程继承的特性,而不仅仅是我希望它们被继承的那些。所以我开始了在CreateProcess 函数来解决这个问题,但我被卡住了。

如果我在 UpdateProcThreadAttribute 过程中使用 PROC_THREAD_ATTRIBUTE_HANDLE_LIST 作为 Attribute 参数,它期望 lpValue 参数是指向列表的指针子进程要继承的句柄数。

对于我尝试使用的列表

TList<Cardinal>

还创建了一个 Cardinals 数组,但无法获得任何编译方法!

问题:如何创建和填充这样的列表?

其次,in this example 使用的是 kernel32.dll 中的函数和过程,但它们也存在于 Windows 单元中(我使用的是 Delphi 10.3),尽管定义不同:

例如,InitializeProcThreadAttributeList( nil, 1, 0, vAListSize ); 由于 nil 参数而无法使用 Windows 单元进行编译,因为 实际和正式 var 参数的类型必须相同 但我使用内核32

问题:我应该使用这些函数/程序的哪个版本?

谢谢。

【问题讨论】:

  • 您需要将指针传递给句柄数组 (HANDLE h[n])
  • 当函数需要THandle 时,为什么你会想到使用Cardinal?如果您不能将nil 传递给InitializeProcThreadAttributeList,那么我怀疑您应该自己声明InitializeProcThreadAttributeList,然后做对。这就是我所做的 FWIW
  • 好问题!我可能到达那里是因为定义上写着“pValue - System.Cardinal”,我一直在尝试各种方法来让它工作但无济于事!并且在其中 vMyHandles 是句柄数组的 UpdateProcThreadAttribute 中使用 @vMyHandles 无法编译。我对使用指针有点困惑
  • 不要将 IDE 用作 Windows API 的参考。使用实际的 Windows API 参考。并且不要相信 Emba 标题翻译。他们经常是错的。
  • @vMyHandles 是指向数组地址的指针。那是间接的一级太远了。不管怎样,我的回答中你有你需要的一切。

标签: delphi winapi vcl kernel32


【解决方案1】:

如果它有用,这是我实现所有这些的代码:

type
  TStartupInfoEx = record
    StartupInfo: TStartupInfo;
    lpAttributeList: Pointer;
  end;

const
  PROC_THREAD_ATTRIBUTE_HANDLE_LIST = $00020002;

function InitializeProcThreadAttributeList(
  lpAttributeList: Pointer;
  dwAttributeCount: DWORD;
  dwFlags: DWORD;
  var lpSize: SIZE_T
): BOOL; stdcall; external kernel32;

function UpdateProcThreadAttribute(
  lpAttributeList: Pointer;
  dwFlags: DWORD;
  Attribute: DWORD_PTR;
  lpValue: Pointer;
  cbSize: SIZE_T;
  lpPreviousValue: PPointer;
  lpReturnSize: PSIZE_T
): BOOL; stdcall; external kernel32;

function DeleteProcThreadAttributeList(
  lpAttributeList: Pointer
): BOOL; stdcall; external kernel32;

function CreateProcessWithInheritedHandles(
  lpApplicationName: LPCWSTR;
  lpCommandLine: LPWSTR;
  lpProcessAttributes,
  lpThreadAttributes: PSecurityAttributes;
  const Handles: array of THandle;
  dwCreationFlags: DWORD;
  lpEnvironment: Pointer;
  lpCurrentDirectory: LPCWSTR;
  const lpStartupInfo: TStartupInfo;
  var lpProcessInformation: TProcessInformation
): Boolean;
var
  i: Integer;
  StartupInfoEx: TStartupInfoEx;
  size: SIZE_T;
begin
  Assert(Length(Handles)>0);

  StartupInfoEx.StartupInfo := lpStartupInfo;
  StartupInfoEx.StartupInfo.cb := SizeOf(StartupInfoEx);
  StartupInfoEx.lpAttributeList := nil;

  Win32Check(not InitializeProcThreadAttributeList(nil, 1, 0, size) and (GetLastError=ERROR_INSUFFICIENT_BUFFER));
  GetMem(StartupInfoEx.lpAttributeList, size);
  try
    Win32Check(InitializeProcThreadAttributeList(StartupInfoEx.lpAttributeList, 1, 0, size));
    try
      Win32Check(UpdateProcThreadAttribute(
        StartupInfoEx.lpAttributeList,
        0,
        PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
        @Handles[0],
        Length(Handles) * SizeOf(Handles[0]),
        nil,
        nil
      ));

      for i := 0 to High(Handles) do begin
        Win32Check(SetHandleInformation(Handles[i], HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT));
      end;

      Result := CreateProcess(
        lpApplicationName,
        lpCommandLine,
        lpProcessAttributes,
        lpThreadAttributes,
        True,
        dwCreationFlags,
        lpEnvironment,
        lpCurrentDirectory,
        StartupInfoEx.StartupInfo,
        lpProcessInformation
      );
    finally
      DeleteProcThreadAttributeList(StartupInfoEx.lpAttributeList);
    end;
  finally
    FreeMem(StartupInfoEx.lpAttributeList);
  end;
end;

从您的帖子看来,在最新版本的 Delphi 中,Windows 单元中有一些 InitializeProcThreadAttributeListUpdateProcThreadAttributeDeleteProcThreadAttributeList 的声明,但您的帖子暗示它们的声明不正确。上面的代码可以正常工作。

【讨论】:

    猜你喜欢
    • 2012-08-08
    • 1970-01-01
    • 2021-07-17
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多