首页 > 解决方案 > 如何为函数 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

错误是

错误 CA2101
为降低安全风险,将字段“MapiMessage.subject”编组为 Unicode,方法是将“MapiMessage”上的 StructLayout.CharSet 设置为 CharSet.Unicode,或将字段显式编组为 UnmanagedType.LPWStr。如果您需要将此字符串编组为 ANSI 或系统相关,请显式指定 MarshalAs,使用 BestFitMapping 属性关闭最佳拟合映射,并为了增加安全性,打开 ThrowOnUnmappableChar。

结构 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 而不会出现错误消息。

我到底该怎么做才能修复这个错误?

标签: c#vb.netvisual-studio-2019marshallingroslyn-code-analysis

解决方案


我可以得到您遇到的代码分析错误的唯一方法是启用已折旧的“二进制分析器 - 在构建时运行选项”。

二进制分析器 - 在构建选项上运行

以下属性组合消除了“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

推荐阅读