如何为函数 MAPISendMail 指定编组

How to specify Marshalling for the function MAPISendMail

自升级到 Visual Studio 16.8.1 后,我的(有点旧)VB.NET 项目中的代码分析出现了很多错误。

以下 DLLImport 有一个错误

<DllImport("MAPI32.DLL")> _
Private Shared Function MAPISendMail ( ByVal sess     As IntPtr, _
                                       ByVal hwnd     As IntPtr, _
                                       ByVal message  As MapiMessage, _
                                       ByVal flg      As Integer, _
                                       ByVal rsv      As Integer ) As Integer
End Function

错误是

Error CA2101
To reduce security risk, marshal field 'MapiMessage.subject' as Unicode, by setting StructLayout.CharSet on 'MapiMessage' to CharSet.Unicode, or by explicitly marshaling the field as UnmanagedType.LPWStr. If you need to marshal this string as ANSI or system-dependent, specify MarshalAs explicitly, use the BestFitMapping attribute to turn best-fit mapping off, and for added security, to turn ThrowOnUnmappableChar on.

结构 MAPI 消息定义为

<StructLayout(LayoutKind.Sequential)> _
Public Class MapiMessage
  Public reserved       As Integer
  Public subject        As String
  Public noteText       As String
  Public messageType    As String
  Public dateReceived   As String
  Public conversationID As String
  Public flags          As Integer
  Public originator     As IntPtr
  Public recipCount     As Integer
  Public recips         As IntPtr
  Public fileCount      As Integer
  Public files          As IntPtr
End Class

我试过在两个函数

上指定CharSet.Ansi
<DllImport("MAPI32.DLL", CharSet := CharSet.Ansi)> _
Private Shared Function MAPISendMail ( ByVal sess     As IntPtr, _
                                       ByVal hwnd     As IntPtr, _
                                       ByVal message  As MapiMessage, _
                                       ByVal flg      As Integer, _
                                       ByVal rsv      As Integer ) As Integer
End Function

和结构

<StructLayout(LayoutKind.Sequential, CharSet := CharSet.Ansi)> _
Public Class MapiMessage
  ...
End Class

并且还尝试在字段主题上指定 MarshalAs(UnmanagedType.LPStr)。

<MarshalAs(UnmanagedType.LPStr)> _
Public subject        As String

我还尝试按照错误消息中的建议指定 BestFitMapping = false 和 ThrowOnUnmappableChar = true。

<DllImport("MAPI32.DLL", CharSet := CharSet.Ansi, BestFitMapping := False, ThrowOnUnmappableChar := True)> _
Private Shared Function MAPISendMail ( ByVal sess     As IntPtr, _
                                       ByVal hwnd     As IntPtr, _
                                       ByVal message  As MapiMessage, _
                                       ByVal flg      As Integer, _
                                       ByVal rsv      As Integer ) As Integer
End Function

我仍然遇到同样的错误。

我还没有尝试使用 MAPISendMailW(而且我还没有找到示例),但即使它提供了解决方案,也肯定有一种方法可以在没有错误消息的情况下编组为 ANSI。

我究竟需要做什么来修复这个错误?

我得到你遇到的代码分析错误的唯一方法是启用已被贬低的“二进制分析器 - 运行 on build option”。

以下属性组合消除了“CA2101”错误。

<DllImport("MAPI32.DLL")>
Private Shared Function MAPISendMail(ByVal sess As IntPtr,
                                      ByVal hwnd As IntPtr,
                                      ByVal message As MapiMessage,
                                      ByVal flg As Integer,
                                      ByVal rsv As Integer) As Integer
End Function

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi),
              BestFitMapping(False, ThrowOnUnmappableChar:=True)>
Public Class MapiMessage
  Public reserved As Integer
  <MarshalAs(UnmanagedType.LPTStr)> Public subject As String
  <MarshalAs(UnmanagedType.LPTStr)> Public noteText As String
  <MarshalAs(UnmanagedType.LPTStr)> Public messageType As String
  <MarshalAs(UnmanagedType.LPTStr)> Public dateReceived As String
  <MarshalAs(UnmanagedType.LPTStr)> Public conversationID As String
  Public flags As Integer
  Public originator As IntPtr
  Public recipCount As Integer
  Public recips As IntPtr
  Public fileCount As Integer
  Public files As IntPtr
End Class