CA2205: Use managed equivalents of Win32 API

Item Value
RuleId CA2205
Category Microsoft.Usage
Breaking change Non-breaking

Cause

A platform invoke method is defined and a method with the equivalent functionality exists in .NET.

Rule description

A platform invoke method is used to call an unmanaged DLL function and is defined using the System.Runtime.InteropServices.DllImportAttribute attribute, or the Declare keyword in Visual Basic. An incorrectly defined platform invoke method can lead to run-time exceptions because of issues such as a misnamed function, faulty mapping of parameter and return value data types, and incorrect field specifications, such as the calling convention and character set. If available, it is simpler and less error prone to call the equivalent managed method than to define and call the unmanaged method directly. Calling a platform invoke method can also lead to additional security issues that need to be addressed.

How to fix violations

To fix a violation of this rule, replace the call to the unmanaged function with a call to its managed equivalent.

When to suppress warnings

Suppress a warning from this rule if the suggested replacement method does not provide the needed functionality.

Example

The following example shows a platform invoke method definition that violates the rule. In addition, the calls to the platform invoke method and the equivalent managed method are shown.

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