2009-09-15 3 views
3

Я пытаюсь PInvoke UpdateProcThreadAttribute() на Windows 7, но мои попытки просто сохранить возвращение FALSE с последней Win32 Error 50..NET: Как PInvoke UpdateProcThreadAttribute

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 
); 

Вот моя попытка подписи PInvoke:

[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 
); 

Является ли это заявление разумным? Благодарю.

+0

всегда стоит проверить http://www.pinvoke.net/ на эти проблемы. –

ответ

2

У вас есть несколько проблем с объявлением, но тот, который дает вам не поддерживаемую ошибку, является параметром атрибута. DWORD_PTR не является указателем, а скорее целым числом без знака указателя, а не refuint, это должен быть IntPtr.

Декларация Я хотел бы использовать это:

[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:

Я пытался сделать это в качестве комментария, но он не принимает в коде очень хорошо.

Для дескриптора процесса вам понадобится IntPtr для удерживания ручки. Так что вам понадобится что-то вроде:

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. 
+0

Спасибо. Я обновил подпись, но все равно получаю 50. Как вы рекомендуете настраивать, скажем, lpValue, чтобы удерживать дескриптор процесса. Я имею это как IntPtr (pHandle, скажем), поэтому я просто передаю это прямо, и для cbSize сделайте что-то вроде: IntPtr pSize = (System.IntPtr) (Marshal.SizeOf (pHandle)); ? Обычно мои pinvokes в порядке, но этот кажется особенно дьявольским. Я очень благодарен за ваш ответ. Спасибо. – mrbouffant

+0

Большое спасибо. Вы помогли мне почти добраться туда. Теперь я получаю ошибку 24 (плохая длина). В приведенном выше примере вы говорили о передаче IntPtr.Size в качестве параметра cbSize, тогда как в вашем исходном сообщении вы имели это как IntPtr. Я попробовал IntPtr lpSize = Marshal.AllocHGlobal (IntPtr.Size); Marshal.WriteInt32 (lpSize, IntPtr.Size) и передавая это через. Ясно, что это неправильно, но я не могу понять, что должно быть правильным использованием. Есть идеи? Благодарю. – mrbouffant

+0

Извините, я отказался от конверсии. Он должен быть (IntPtr) IntPtr.Size. Я исправил этот пост. –

Смежные вопросы