2009-09-15 7 views
3

Je suis en train de PInvoke UpdateProcThreadAttribute() sur Windows 7, mais mes tentatives continue juste à retourner FALSE avec une dernière erreur Win32 de 50..NET: Comment 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 
); 

Voici ma tentative de la signature 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 
); 

Cette déclaration est-elle sensée? Merci.

+0

il est toujours préférable de vérifier http://www.pinvoke.net/ pour ce type de problèmes. –

Répondre

2

Vous avez quelques problèmes avec votre déclaration mais celui qui vous donne l'erreur non prise en charge est le paramètre Attribute. Un DWORD_PTR n'est pas un pointeur, mais plutôt un pointeur non signé de taille pointeur donc plutôt que ref uint il devrait être un IntPtr.

La déclaration que je voudrais utiliser est:

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

J'ai essayé de le faire comme commentaire, mais il ne prend pas au code très bien.

Pour une poignée de processus, vous avez besoin d'un IntPtr pour tenir la poignée. Donc, vous auriez besoin de quelque chose comme:

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

Merci pour ça. J'ai mis à jour la signature mais j'obtiens toujours 50. Comment recommandez-vous de mettre en place, disons, lpValue pour contenir le handle d'un processus. Je l'ai comme un IntPtr (pHandle, disons) alors je passe juste cela directement et pour cbSize faire quelque chose comme: IntPtr pSize = (System.IntPtr) (Marshal.SizeOf (pHandle)); ? Normalement, mes pinvokes sont OK, mais celui-ci semble particulièrement diabolique. Je suis très reconnaissant pour votre réponse. Je vous remercie. – mrbouffant

+0

Merci beaucoup. Vous m'avez aidé à y arriver. Maintenant, j'ai l'erreur 24 (mauvaise longueur). Dans votre exemple ci-dessus, vous avez parlé de passer IntPtr.Size en tant que paramètre cbSize, alors que dans votre message d'origine, vous aviez ceci comme un IntPtr. J'ai essayé IntPtr lpSize = Marshal.AllocHGlobal (IntPtr.Size); Marshal.WriteInt32 (lpSize, IntPtr.Size) et en passant cela. De toute évidence, c'est faux, mais je ne peux pas déterminer quel devrait être le bon usage. Des idées? Merci. – mrbouffant

+0

Désolé, j'ai omis la conversion. Il devrait être (IntPtr) IntPtr.Size. J'ai corrigé le post. –

Questions connexes