GetMessage id 超出搜索范围
GetMessage id out of range from search scope
我正在尝试使用 Powershell 中的 MailKit 连接到 IMAP 服务器。
连接到服务器,打开收件箱,搜索子文件夹,select 并打开子文件夹,查询所有消息 (SeqrchQuery) 并尝试获取最后一条消息。
示例代码:
'BouncyCastle.Crypto', 'mimekit', 'mailkit', 'Microsoft.Extensions.Options', 'cloudscribe.Messaging.Email' | %{Add-Type -Path "$(Join-Path 'D:\Mailkit' ($_ + '.dll'))"}
$mll = New-Object MailKit.Net.Imap.ImapClient
$ctoken = New-Object System.Threading.CancellationToken ($false)
$ssl = [MailKit.Security.SecureSocketOptions]::Auto
$mll.Connect('server.name', 993, $ssl, $ctoken)
$mll.Authenticate(([System.Text.Encoding]::UTF8) , "user@server.name", "pass" , $ctoken)
$inbox = $mll.Inbox
$inbox.Open([MailKit.FolderAccess]::ReadOnly) | Out-Null
$inbox = $inbox.GetSubfolders($false) | ?{$_.Name -eq 'SUBFOLDER'}
$inbox.Open([MailKit.FolderAccess]::ReadOnly) | Out-Null
$src = $inbox.Search([MailKit.Search.SearchQuery]::All)
$msg = $src | select -Last 1
try {$inbox.GetMessage($msg.Id)}
catch {
$_
}
$inbox.Close()
$mll.Disconnect($true , $ctoken)
Remove-Variable mll,inbox,msg,src,ctoken,ssl
并得到错误:
Exception calling "GetMessage" with "1" argument(s): "Argument value out of range.
Parameter name: index"
At line:23 char:1
+ $inbox.GetMessage($msg.Id)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentOutOfRangeException
您遇到的问题是 MailKit 有 2 个版本 ImapFolder.GetMessage()
:
ImapFolder.GetMessage (int index)
ImapFolder.GetMessage (UniqueId uid)
Search()
方法 returns UniqueId
值的列表。 UniqueId
结构有一个名为 Id
的成员,它是一个 uint
.
当您将 $msg.Id
传递给 GetMessage()
时,它会调用 API 的 int
版本,而不是 UniqueId
版本。
对于 IMAP,有两种访问邮件的方式。您可以通过它们的索引访问它们,也可以通过它们的唯一标识符访问它们。
它们看起来都是整数,但它们不能互换。
您需要使用$inbox.GetMessage ($msg)
。
感谢@jstedfast 的解释。
为了正确工作,我必须在方法调用中定义变量类型。
正确代码:
$mll = New-Object MailKit.Net.Imap.ImapClient
$ctoken = New-Object System.Threading.CancellationToken ($false)
$ssl = [MailKit.Security.SecureSocketOptions]::Auto
$mll.Connect('server.name', 993, $ssl, $ctoken)
$mll.Authenticate(([System.Text.Encoding]::UTF8) , "user@server.name", "pass" , $ctoken)
$inbox = $mll.Inbox
$inbox.Open([MailKit.FolderAccess]::ReadOnly) | Out-Null
$inbox = $inbox.GetSubfolders($false) | ?{$_.Name -eq 'SUBFOLDER'}
$inbox.Open([MailKit.FolderAccess]::ReadOnly) | Out-Null
$src = $inbox.Search([MailKit.Search.SearchQuery]::All)
$msg = $src | select -Last 1
try { $id = [MailKit.UniqueId]($msg.Id) ; $inbox.GetMessage($id) }
catch { $_ }
$inbox.Close()
$mll.Disconnect($true , $ctoken)
这应该使用您的 Uint 值创建一个 UID:
$UID = New-Object Mailkit.UniqueId(Msg.Id)
然后使用 $UID 而不是 msg.id
调用您的 inbox.getMessage
try {
$inbox.GetMessage($UID)
} catch {
$_
}
我正在尝试使用 Powershell 中的 MailKit 连接到 IMAP 服务器。 连接到服务器,打开收件箱,搜索子文件夹,select 并打开子文件夹,查询所有消息 (SeqrchQuery) 并尝试获取最后一条消息。 示例代码:
'BouncyCastle.Crypto', 'mimekit', 'mailkit', 'Microsoft.Extensions.Options', 'cloudscribe.Messaging.Email' | %{Add-Type -Path "$(Join-Path 'D:\Mailkit' ($_ + '.dll'))"}
$mll = New-Object MailKit.Net.Imap.ImapClient
$ctoken = New-Object System.Threading.CancellationToken ($false)
$ssl = [MailKit.Security.SecureSocketOptions]::Auto
$mll.Connect('server.name', 993, $ssl, $ctoken)
$mll.Authenticate(([System.Text.Encoding]::UTF8) , "user@server.name", "pass" , $ctoken)
$inbox = $mll.Inbox
$inbox.Open([MailKit.FolderAccess]::ReadOnly) | Out-Null
$inbox = $inbox.GetSubfolders($false) | ?{$_.Name -eq 'SUBFOLDER'}
$inbox.Open([MailKit.FolderAccess]::ReadOnly) | Out-Null
$src = $inbox.Search([MailKit.Search.SearchQuery]::All)
$msg = $src | select -Last 1
try {$inbox.GetMessage($msg.Id)}
catch {
$_
}
$inbox.Close()
$mll.Disconnect($true , $ctoken)
Remove-Variable mll,inbox,msg,src,ctoken,ssl
并得到错误:
Exception calling "GetMessage" with "1" argument(s): "Argument value out of range.
Parameter name: index"
At line:23 char:1
+ $inbox.GetMessage($msg.Id)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentOutOfRangeException
您遇到的问题是 MailKit 有 2 个版本 ImapFolder.GetMessage()
:
ImapFolder.GetMessage (int index)
ImapFolder.GetMessage (UniqueId uid)
Search()
方法 returns UniqueId
值的列表。 UniqueId
结构有一个名为 Id
的成员,它是一个 uint
.
当您将 $msg.Id
传递给 GetMessage()
时,它会调用 API 的 int
版本,而不是 UniqueId
版本。
对于 IMAP,有两种访问邮件的方式。您可以通过它们的索引访问它们,也可以通过它们的唯一标识符访问它们。
它们看起来都是整数,但它们不能互换。
您需要使用$inbox.GetMessage ($msg)
。
感谢@jstedfast 的解释。 为了正确工作,我必须在方法调用中定义变量类型。 正确代码:
$mll = New-Object MailKit.Net.Imap.ImapClient
$ctoken = New-Object System.Threading.CancellationToken ($false)
$ssl = [MailKit.Security.SecureSocketOptions]::Auto
$mll.Connect('server.name', 993, $ssl, $ctoken)
$mll.Authenticate(([System.Text.Encoding]::UTF8) , "user@server.name", "pass" , $ctoken)
$inbox = $mll.Inbox
$inbox.Open([MailKit.FolderAccess]::ReadOnly) | Out-Null
$inbox = $inbox.GetSubfolders($false) | ?{$_.Name -eq 'SUBFOLDER'}
$inbox.Open([MailKit.FolderAccess]::ReadOnly) | Out-Null
$src = $inbox.Search([MailKit.Search.SearchQuery]::All)
$msg = $src | select -Last 1
try { $id = [MailKit.UniqueId]($msg.Id) ; $inbox.GetMessage($id) }
catch { $_ }
$inbox.Close()
$mll.Disconnect($true , $ctoken)
这应该使用您的 Uint 值创建一个 UID:
$UID = New-Object Mailkit.UniqueId(Msg.Id)
然后使用 $UID 而不是 msg.id
调用您的 inbox.getMessagetry {
$inbox.GetMessage($UID)
} catch {
$_
}