Pergunta

Eu estou tentando PInvoke UpdateProcThreadAttribute() no Windows 7, mas minhas tentativas apenas manter retornando FALSE com um erro de Última Win32 de 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
);

Aqui está a minha tentativa da assinatura 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
);

É este sensata declaração? Obrigado.

Foi útil?

Solução

Você tem alguns problemas com a sua declaração, mas o que está lhe dando o erro não suportado é o parâmetro Atributo. A DWORD_PTR não é um ponteiro, mas sim um ponteiro tamanho inteiro sem sinal então ao invés de uint ref deve ser um IntPtr.

A declaração eu usaria é:

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

Eu tentei fazer isso como um comentário, mas ele não leva ao código muito bem.

Para um identificador de processo que você precisa de um IntPtr para segurar a alça. Então você precisa de algo como:

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.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top