Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
905 views
in Technique[技术] by (71.8m points)

c# - .NET : How to PInvoke UpdateProcThreadAttribute

I am trying to PInvoke UpdateProcThreadAttribute() on Windows 7 but my attempts just keep returning FALSE with a Last Win32 Error of 50.

Function declaration (from MSDN)

BOOL WINAPI UpdateProcThreadAttribute(
  __inout    LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList,
  __in       DWORD dwFlags,
  __in       DWORD_PTR Attribute,
  __in       PVOID lpValue,
  __in       SIZE_T cbSize,
  __out_opt  PVOID lpPreviousValue,
  __in_opt   PSIZE_T lpReturnSize
);

Here is my attempt at the PInvoke signature:

[DllImport("kernel32.dll", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
public static extern bool UpdateProcThreadAttribute
(
            IntPtr lpAttributeList,
            UInt32 dwFlags,
            ref UInt32 Attribute,
            ref IntPtr lpValue,
            ref IntPtr cbSize,
            IntPtr lpPreviousValue,
            IntPtr lpReturnSize
);

Is this declaration sensible? Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You have a few problems with your declaration but the one that is giving you the not supported error is the Attribute parameter. A DWORD_PTR is not a pointer but rather a pointer sized unsigned integer so rather than ref uint it should be an IntPtr.

The declaration I would use is:

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool UpdateProcThreadAttribute(
        IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute,
        IntPtr lpValue, IntPtr cbSize, IntPtr lpPreviousValue, 
        IntPtr lpReturnSize);

EDIT:

I tried to do this as a comment but it doesn't take to code very well.

For a process handle you need an IntPtr to hold the handle. So you would need something like:

IntPtr hProcess //previously retrieved.
IntPtr lpAttributeList //previously allocated using InitializeProcThreadAttributeList and Marshal.AllocHGlobal.

const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000;
IntPtr lpValue = Marshal.AllocHGlobal(IntPtr.Size); 
Marshal.WriteIntPtr(lpValue, hProcess);
if(UpdateProcThreadAttribute(lpAttributeList, 0, (IntPtr)PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, lpValue, (IntPtr)IntPtr.Size, IntPtr.Zero, IntPtr.Zero))
{
    //do something
}

//Free lpValue only after the lpAttributeList is deleted.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...