CA1060:P/Invoke を NativeMethods クラスに移動しますCA1060: Move P/Invokes to NativeMethods class

TypeNameTypeName MovePInvokesToNativeMethodsClassMovePInvokesToNativeMethodsClass
CheckIdCheckId CA1060CA1060
カテゴリCategory Microsoft.DesignMicrosoft.Design
互換性に影響する変更点Breaking Change ありBreaking

原因Cause

メソッドはアンマネージ コードへのアクセス プラットフォーム呼び出しサービスを使用してのいずれかのメンバーではない、 NativeMethodsクラス。A method uses Platform Invocation Services to access unmanaged code and is not a member of one of the NativeMethods classes.

規則の説明Rule description

使用してマークされているなどのプラットフォーム呼び出しメソッド、System.Runtime.InteropServices.DllImportAttribute属性、またはを使用して定義されているメソッド、DeclareキーワードVisual BasicVisual Basic、アンマネージ コードにアクセスします。Platform Invocation methods, such as those that are marked by using the System.Runtime.InteropServices.DllImportAttribute attribute, or methods that are defined by using the Declare keyword in Visual BasicVisual Basic, access unmanaged code. 次のクラスのいずれかでこれらのメソッドがあります。These methods should be in one of the following classes:

  • NativeMethods -このクラスがアンマネージ コード アクセス許可のスタック ウォークを抑制できません。NativeMethods - This class does not suppress stack walks for unmanaged code permission. (System.Security.SuppressUnmanagedCodeSecurityAttributeこのクラスに適用する必要がありません)。このクラスでは、メソッドのスタック ウォークを実行するため、どこでも使用できます。(System.Security.SuppressUnmanagedCodeSecurityAttribute must not be applied to this class.) This class is for methods that can be used anywhere because a stack walk will be performed.

  • SafeNativeMethods -このクラスがアンマネージ コード アクセス許可のスタック ウォークを抑制します。SafeNativeMethods - This class suppresses stack walks for unmanaged code permission. (System.Security.SuppressUnmanagedCodeSecurityAttributeこのクラスに適用されます)。このクラスは、メソッドを呼び出すすべてのユーザーに対して安全なは。(System.Security.SuppressUnmanagedCodeSecurityAttribute is applied to this class.) This class is for methods that are safe for anyone to call. これらのメソッドの呼び出し元は、呼び出し元の害のない方法であるため、使用量が安全であるかどうかを確認する完全なセキュリティ レビューを実行する必要はありません。Callers of these methods are not required to perform a full security review to make sure that the usage is secure because the methods are harmless for any caller.

  • UnsafeNativeMethods -このクラスがアンマネージ コード アクセス許可のスタック ウォークを抑制します。UnsafeNativeMethods - This class suppresses stack walks for unmanaged code permission. (System.Security.SuppressUnmanagedCodeSecurityAttributeこのクラスに適用されます)。このクラスは、危険なメソッドです。(System.Security.SuppressUnmanagedCodeSecurityAttribute is applied to this class.) This class is for methods that are potentially dangerous. これらのメソッドの呼び出し元は、スタック ウォークは実行しないため、使用量が安全であるかどうかを確認する完全なセキュリティ レビューを実行する必要があります。Any caller of these methods must perform a full security review to make sure that the usage is secure because no stack walk will be performed.

としてこれらのクラスが宣言されているinternal(Friend、Visual Basic で) し、新しいインスタンスが作成されないようにする、プライベート コンス トラクターを宣言します。These classes are declared as internal (Friend, in Visual Basic) and declare a private constructor to prevent new instances from being created. これらのクラスのメソッドにする必要がありますstaticinternal(SharedFriendVisual Basic で)。The methods in these classes should be static and internal (Shared and Friend in Visual Basic).

違反の修正方法How to fix violations

このルールの違反を修正するには、適切なメソッドを移動NativeMethodsクラス。To fix a violation of this rule, move the method to the appropriate NativeMethods class. ほとんどのアプリケーションで P/invoke を移動という新しいクラスにNativeMethods十分です。For most applications, moving P/Invokes to a new class that is named NativeMethods is enough.

ただし、他のアプリケーションで使用するライブラリを開発している場合は、検討するくださいと呼ばれるその他の 2 つのクラスを定義するSafeNativeMethodsUnsafeNativeMethodsします。However, if you are developing libraries for use in other applications, you should consider defining two other classes that are called SafeNativeMethods and UnsafeNativeMethods. これらのクラスのように、 NativeMethodsクラス。 ただし、と呼ばれる特殊な属性を使用してマークされているSuppressUnmanagedCodeSecurityAttributeします。These classes resemble the NativeMethods class; however, they are marked by using a special attribute called SuppressUnmanagedCodeSecurityAttribute. この属性が適用されるときに、ランタイムがすべての呼び出し元があることを確認する完全なスタック ウォークを実行しない、 UnmanagedCode権限。When this attribute is applied, the runtime does not perform a full stack walk to make sure that all callers have the UnmanagedCode permission. ランタイムは、通常、起動時にこのアクセス許可をチェックします。The runtime ordinarily checks for this permission at startup. チェックが実行されないため、これらのアンマネージ メソッドを呼び出す際のパフォーマンスを大幅に向上することができます、コードをこれらのメソッドを呼び出すアクセス許可が制限されていることもできます。Because the check is not performed, it can greatly improve performance for calls to these unmanaged methods, It also enables code that has limited permissions to call these methods.

ただし、十分に注意して、この属性を使用する必要があります。However, you should use this attribute with great care. これが正しく実装されていない場合、重大なセキュリティへの影響ができます.It can have serious security implications if it is implemented incorrectly..

メソッドを実装する方法については、次を参照してください。、 NativeMethods例では、 SafeNativeMethods例では、とUnsafeNativeMethods例。For information about how to implement the methods, see the NativeMethods Example, SafeNativeMethods Example, and UnsafeNativeMethods Example.

警告を抑制します。When to suppress warnings

この規則による警告は抑制しないでください。Do not suppress a warning from this rule.

Example

次の例では、この規則に違反するメソッドを宣言します。The following example declares a method that violates this rule. 違反を修正する、 RemoveDirectory P/invoke は、P/invoke のみを保持するように設計された適切なクラスに移動する必要があります。To correct the violation, the RemoveDirectory P/Invoke should be moved to an appropriate class that is designed to hold only 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 例NativeMethods Example

説明Description

NativeMethodsクラスを使用してマークしないでSuppressUnmanagedCodeSecurityAttributeが必要になりますが格納される P/invoke UnmanagedCodeアクセス許可。Because the NativeMethods class should not be marked by using SuppressUnmanagedCodeSecurityAttribute, P/Invokes that are put in it will require UnmanagedCode permission. ローカル コンピューターからほとんどのアプリケーションが実行され、完全な信頼と一緒に実行すると、この問題には、通常は。Because most applications run from the local computer and run together with full trust, this is usually not a problem. ただし、再利用可能なライブラリを開発している場合は、する必要がありますを定義する、 SafeNativeMethodsまたはUnsafeNativeMethodsクラス。However, if you are developing reusable libraries, you should consider defining a SafeNativeMethods or UnsafeNativeMethods class.

次の例は、 Interaction.Beepをラップするメソッド、 MessageBeep user32.dll から関数。The following example shows an Interaction.Beep method that wraps the MessageBeep function from user32.dll. MessageBeep P/invoke は、配置、 NativeMethodsクラス。The MessageBeep P/Invoke is put in the NativeMethods class.

コードCode

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

SafeNativeMethods 例SafeNativeMethods Example

説明Description

任意のアプリケーションに安全に公開して、副作用がない、P/invoke メソッドは、というクラスに配置する必要がありますSafeNativeMethodsします。P/Invoke methods that can be safely exposed to any application and that do not have any side effects should be put in a class that is named SafeNativeMethods. アクセス許可を要求する必要はありませんしから呼び出されたに多くの注意を払う必要はありません。You do not have to demand permissions and you do not have to pay much attention to where they are called from.

次の例は、 Environment.TickCountプロパティをラップする、 GetTickCount関数を kernel32.dll から。The following example shows an Environment.TickCount property that wraps the GetTickCount function from kernel32.dll.

コードCode

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

UnsafeNativeMethods の例UnsafeNativeMethods Example

説明Description

という名前のクラスでは P/invoke メソッドを安全に呼び出すし、副作用を引き起こす可能性を含める必要がありますUnsafeNativeMethodsします。P/Invoke methods that cannot be safely called and that could cause side effects should be put in a class that is named UnsafeNativeMethods. これらのメソッドは、これらは、ユーザーに意図せずになっていることを確認する厳密にチェックする必要があります。These methods should be rigorously checked to make sure that they are not exposed to the user unintentionally. ルールCA2118:SuppressUnmanagedCodeSecurityAttribute の使用法の確認これを支援できます。The rule CA2118: Review SuppressUnmanagedCodeSecurityAttribute usage can help with this. 代わりに要求されるもう 1 つのアクセスを許可するメソッドが代わりに、ありますUnmanagedCodeに使用するとします。Alternatively, the methods should have another permission that is demanded instead of UnmanagedCode when they use them.

次の例は、 Cursor.Hideをラップするメソッド、 ShowCursor user32.dll から関数。The following example shows a Cursor.Hide method that wraps the ShowCursor function from user32.dll.

コードCode

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

関連項目See also