Compartilhar via


Mover P/Invokes para classe NativeMethods

TypeName

MovePInvokesToNativeMethodsClass

CheckId

CA1060

Category (Categoria)

Microsoft.Design

Quebrando alterar

Quebrando

Causa

Um método usa plataforma Invocation Services para acesso código não gerenciado e não é um membro de um a NativeMethods classes.

Descrição da regra

Métodos de invocação de plataforma, sistema autônomo aqueles marcados com o System.Runtime.InteropServices.DllImportAttribute atributo ou métodos definidos usando o Declare palavra-chave no Visual Basic, acessar código não gerenciado. Esses métodos devem ter uma das seguintes classes:

  • NativeMethods - Esta classe não suprime as movimentações de pilha para permissão de código não gerenciado.(System.Security.SuppressUnmanagedCodeSecurityAttribute deve não ser aplicada a essa classe.) Essa classe é para métodos que podem ser usados em qualquer lugar porque um exame da pilha será executado.

  • SafeNativeMethods - Suprime a essa classe pilha walks para permissão de código não gerenciado.(System.Security.SuppressUnmanagedCodeSecurityAttribute é aplicada a essa classe.) Essa classe é para métodos que são seguros para qualquer pessoa telefonar.Os chamadores desses métodos não são necessários para fazer uma revisão de segurança completa para garantir que o uso é seguro porque os métodos são inofensivos para qualquer chamador.

  • UnsafeNativeMethods - Suprime a essa classe pilha walks para permissão de código não gerenciado.(System.Security.SuppressUnmanagedCodeSecurityAttribute é aplicada a essa classe.) Essa classe é para os métodos são potencialmente perigosos.Qualquer chamador destes métodos deverá fazer uma revisão de segurança completa para garantir que o uso é seguro porque nenhuma pilha walk vai ser executada.

Essas classes são declaradas sistema autônomo internal (Friendno Visual Basic), e declara um construtor particular para impedir que novas instâncias que está sendo criado. Os métodos essas classes devem ser static e internal (Shared e Friend no Visual Basic).

Como corrigir violações

Para corrigir uma violação dessa regra, mover o método à apropriado NativeMethods classe.Para a maioria dos aplicativos, mover P/Invokes para uma nova classe chamada NativeMethods é suficiente.

No entanto, se você estiver desenvolvendo bibliotecas para uso em outros aplicativos, você deve considerar definir duas outras classes chamado SafeNativeMethods and UnsafeNativeMethods.Essas classes semelhante a NativeMethods classe, no entanto, eles são marcados com um atributo especial chamado SuppressUnmanagedCodeSecurityAttribute.Quando esse atributo é aplicado, o tempo de execução não realiza um exame da pilha completa para se certificar de que todos os chamadores tem o UnmanagedCode permissão.O tempo de execução normalmente verifica essa permissão na inicialização.Como a verificação não for executada, ele bastante pode melhorar o desempenho de chamadas para esses métodos não gerenciados e também permite que o código com permissões limitadas para chamar esses métodos.

No entanto, você deve usar esse atributo com muito cuidado, pois, implementados incorretamente, ele pode ter sérias implicações de segurança.

Para obter informações sobre como implementar os métodos, consulte o NativeMethods Exemplo, SafeNativeMethods Exemplo e UnsafeNativeMethods Exemplo.

Quando suprimir avisos

Não suprimir um aviso da regra.

Exemplo

O exemplo a seguir declara um método que violam essa regra.Para corrigir a violação, a RemoveDirectory P/Invoke deve ser movido para uma classe apropriada foi criada para conter apenas P/Invokes.

Imports System

NameSpace MSInternalLibrary

' Violates rule: MovePInvokesToNativeMethodsClass.
Friend Class UnmanagedApi
    Friend Declare Function RemoveDirectory Lib "kernel32" ( _
       ByVal Name As String) As Boolean
End Class

End NameSpace 
using System;
using System.Runtime.InteropServices;

namespace DesignLibrary
{
// Violates rule: MovePInvokesToNativeMethodsClass.
    internal class UnmanagedApi
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
        internal static extern bool RemoveDirectory(string name);
    }
}

NativeMethods exemplo

Descrição

Porque o NativeMethods classe não deve ser marcado com SuppressUnmanagedCodeSecurityAttribute, P/Invokes colocados dentro de nela exigirá UnmanagedCode permissão.Como a maioria dos aplicativos é executada no computador local e executar com confiança total, isso geralmente não é um problema.No entanto, se você estiver desenvolvendo bibliotecas reutilizáveis, você deve considerar definindo um SafeNativeMethods or UnsafeNativeMethods classe.

O exemplo a seguir mostra um interação.Beep método que envolve o MessageBeep função em user32.dll.The MessageBeep P/Invoke é colocado dentro de NativeMethods classe.

Código

Imports System    
Imports System.Runtime.InteropServices    
Imports System.ComponentModel         

Public NotInheritable Class Interaction  

    Private Sub New()        
    End Sub                

    ' Callers require Unmanaged permission        
    Public Shared Sub Beep()                        
        ' No need to demand a permission as callers of Interaction.Beep                     
        ' will require UnmanagedCode permission                     
        If Not NativeMethods.MessageBeep(-1) Then                
            Throw New Win32Exception()            
        End If

    End Sub  

End Class         

Friend NotInheritable Class NativeMethods  

    Private Sub New()        
    End Sub             

    <DllImport("user32.dll", CharSet:=CharSet.Auto)> _        
    Friend Shared Function MessageBeep(ByVal uType As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean        
    End Function  

End Class
using System;    
using System.Runtime.InteropServices;    
using System.ComponentModel;              

public static class Interaction    
{        
    // Callers require Unmanaged permission        
    public static void Beep()           
    {            
        // No need to demand a permission as callers of Interaction.Beep            
        // will require UnmanagedCode permission            
        if (!NativeMethods.MessageBeep(-1))                
            throw new Win32Exception();        
    }    
}            

internal static class NativeMethods    
{        
    [DllImport("user32.dll", CharSet = CharSet.Auto)]        
    [return: MarshalAs(UnmanagedType.Bool)]        
    internal static extern bool MessageBeep(int uType);    
}

Exemplo da SafeNativeMethods

Descrição

Métodos P/Invoke que são seguros ser exposto a qualquer aplicativo e que não possuem quaisquer efeitos colaterais devem ser colocados em uma classe chamada SafeNativeMethods.Você não tem permissões de demanda e não é necessário prestar muita atenção onde eles são chamados de.

O exemplo a seguir mostra um ambiente.TickCount propriedade que envolve o ObterContagemMarcaEscala função em kernel32.dll.

Código

Imports System   
Imports System.Runtime.InteropServices   
Imports System.Security       

Public NotInheritable Class Environment       

    Private Sub New()       
    End Sub           

    ' Callers do not require Unmanaged permission       
    Public Shared ReadOnly Property TickCount() As Integer           
        Get               
            ' No need to demand a permission in place of               
            ' UnmanagedCode as GetTickCount is considered               
            ' a safe method               
            Return SafeNativeMethods.GetTickCount()               
        End Get       
    End Property       

End Class       

<SuppressUnmanagedCodeSecurityAttribute()> _   
Friend NotInheritable Class SafeNativeMethods             

    Private Sub New()       
    End Sub           

    <DllImport("kernel32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _       
    Friend Shared Function GetTickCount() As Integer       
    End Function       

End Class
using System;   
using System.Runtime.InteropServices;   
using System.Security;  

public static class Environment   
{       
    // Callers do not require UnmanagedCode permission       
    public static int TickCount        
    {           
        get           
        {              
            // No need to demand a permission in place of               
            // UnmanagedCode as GetTickCount is considered              
            // a safe method              
            return SafeNativeMethods.GetTickCount();           
        }       
    }   
}            

[SuppressUnmanagedCodeSecurityAttribute]   
internal static class SafeNativeMethods   
{       
    [DllImport("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]       
    internal static extern int GetTickCount();   
}

Exemplo de UnsafeNativeMethods

Descrição

Métodos P/Invoke que não são seguros para alguém chamar e que pode causar efeitos colaterais devem ser colocados em uma classe telefonar UnsafeNativeMethods.Esses métodos devem ser verificados rigorosamente para certificar-se de que eles não sejam sendo expostos ao usuário inadvertidamente.A regra Revise o uso de SuppressUnmanagedCodeSecurityAttribute pode ajudar com isso. Como alternativa, os métodos devem ter outra permissão exigida no lugar de UnmanagedCode quando eles usam-los.

O exemplo a seguir mostra um Cursor.ocultar método que envolve o ShowCursor função em user32.dll.

Código

Imports System   
Imports System.Runtime.InteropServices   
Imports System.Security   
Imports System.Security.Permissions       

Public NotInheritable Class Cursor           

    Private Sub New()       
    End Sub           

    ' Callers do not require Unmanaged permission, however,         
    ' they do require UIPermission.AllWindows       
    Public Shared Sub Hide()                 
        ' Need to demand an appropriate permission                   
        ' in  place of UnmanagedCode permission as                    
        ' ShowCursor is not considered a safe method                   
        Dim permission As New UIPermission(UIPermissionWindow.AllWindows)           
        permission.Demand()           
        UnsafeNativeMethods.ShowCursor(False)                

    End Sub       

End Class       

<SuppressUnmanagedCodeSecurityAttribute()> _   
Friend NotInheritable Class UnsafeNativeMethods           

    Private Sub New()       
    End Sub           

    <DllImport("user32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)> _       
    Friend Shared Function ShowCursor(<MarshalAs(UnmanagedType.Bool)> ByVal bShow As Boolean) As Integer       
    End Function       

End Class
using System;   
using System.Runtime.InteropServices;   
using System.Security;   
using System.Security.Permissions;           

public static class Cursor   
{       
    // Callers do not require UnmanagedCode permission, however,       
    // they do require UIPermissionWindow.AllWindows       
    public static void Hide()          
    {           
        // Need to demand an appropriate permission           
        // in  place of UnmanagedCode permission as            
        // ShowCursor is not considered a safe method           
        new UIPermission(UIPermissionWindow.AllWindows).Demand();           
        UnsafeNativeMethods.ShowCursor(false);       
    }   
}            

[SuppressUnmanagedCodeSecurityAttribute]   
internal static class UnsafeNativeMethods   
{       
    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]       
    internal static extern int ShowCursor([MarshalAs(UnmanagedType.Bool)]bool bShow);   
}

Consulte também

Outros recursos

Avisos de design