Share via


CA2205:使用 Win32 API 的托管等效项

类型名

UseManagedEquivalentsOfWin32Api

CheckId

CA2205

类别

Microsoft.Usage

是否重大更改

原因

定义了平台调用方法,但在 .NET Framework 类库中存在具有等效功能的方法。

规则说明

平台调用方法用于调用非托管 DLL 函数,该方法使用 System.Runtime.InteropServices.DllImportAttribute 特性(在 Visual Basic 中使用 Declare 关键字)进行定义。 如果平台调用方法定义不正确,则可能会因错误命名的函数、错误的参数映射和返回值类型、错误的字段说明(如调用约定和字符集)等问题导致运行时异常。 如果存在等效托管方法,则调用等效托管方法通常要比直接定义和调用非托管方法简单的多,并且也不容易发生错误。 调用平台调用方法还会导致其他需要解决的安全问题。

如何解决冲突

要修复与该规则的冲突,请使用对非托管函数的托管等效项的调用来代替对非托管函数的调用。

何时禁止显示警告

如果建议的替代方法无法提供所需的功能,则可以禁止显示此规则发出的警告。

示例

下面的示例演示一个与该规则冲突的平台调用方法定义。 此外,还演示了对该平台调用方法及等效托管方法的调用。

Imports System
Imports System.Runtime.InteropServices
Imports System.Text

Namespace UsageLibrary

   Class NativeMethods

      Private Sub New()
      End Sub

      ' The following method definitions violate the rule.

      <DllImport("kernel32.dll", CharSet := CharSet.Unicode, _ 
         SetLastError := True)> _ 
      Friend Shared Function ExpandEnvironmentStrings _ 
         (lpSrc As String, lpDst As StringBuilder, nSize As Integer) _ 
         As Integer
      End Function

      Friend Declare Unicode Function ExpandEnvironmentStrings2 _ 
         Lib "kernel32.dll" Alias "ExpandEnvironmentStrings" _ 
         (lpSrc As String, lpDst As StringBuilder, nSize As Integer) _ 
         As Integer

   End Class

   Public Class UseNativeMethod

      Shared Sub Main()

         Dim environmentVariable As String = "%TEMP%"
         Dim expandedVariable As New StringBuilder(100)

         ' Call the unmanaged method.
         NativeMethods.ExpandEnvironmentStrings( _ 
            environmentVariable, _ 
            expandedVariable, _ 
            expandedVariable.Capacity)

         ' Call the unmanaged method.
         NativeMethods.ExpandEnvironmentStrings2( _ 
            environmentVariable, _ 
            expandedVariable, _ 
            expandedVariable.Capacity)

         ' Call the equivalent managed method.
         Environment.ExpandEnvironmentVariables(environmentVariable)

      End Sub

   End Class

End Namespace
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace UsageLibrary
{
   internal class NativeMethods
   {
      private NativeMethods() {}

      // The following method definition violates the rule.
      [DllImport("kernel32.dll", CharSet = CharSet.Unicode, 
          SetLastError = true)]
      internal static extern int ExpandEnvironmentStrings(
         string lpSrc, StringBuilder lpDst, int nSize);
   }

   public class UseNativeMethod
   {
      public void Test()
      {
         string environmentVariable = "%TEMP%";
         StringBuilder expandedVariable = new StringBuilder(100);

         // Call the unmanaged method.
         NativeMethods.ExpandEnvironmentStrings(
            environmentVariable, 
            expandedVariable, 
            expandedVariable.Capacity);

         // Call the equivalent managed method.
         Environment.ExpandEnvironmentVariables(environmentVariable);
      }
   }
}

相关规则

CA1404:紧接在 P/Invoke 之后调用 GetLastError

CA1060:将 P/Invoke 移动到 NativeMethods 类

CA1400:P/Invoke 入口点应该存在

CA1401:P/Invokes 应该是不可见的

CA2101:指定对 P/Invoke 字符串参数进行封送处理