无需解压ZIP,用PowerShell解析EML文件From与To字段的问题
解决方案
错误原因
你遇到的问题是ADODB.Stream.LoadFromFile()方法仅支持本地文件路径,而你传入的是ZipArchiveEntry对象(对应压缩包内的文件流),所以触发类型不匹配错误。
方案1:修复CDO.Message的流处理逻辑
无需将文件解压到本地,直接把ZipEntry的流复制到ADODB Stream中,再交给CDO.Message解析:
$zipPath = "你的ZIP文件路径" $zipArchive = [IO.Compression.ZipFile]::OpenRead($zipPath) foreach ($entry in $zipArchive.Entries) { # 只处理EML文件 if (-not $entry.Name.EndsWith(".eml", [StringComparison]::OrdinalIgnoreCase)) { continue } # 读取ZipEntry的流 $zipStream = $entry.Open() # 初始化ADODB Stream并写入Zip流内容 $adoStream = New-Object -ComObject ADODB.Stream $adoStream.Type = 1 # adTypeBinary $adoStream.Open() # 将.NET流转换为字节数组,再写入ADODB Stream $buffer = New-Object byte[] 4096 while (($readBytes = $zipStream.Read($buffer, 0, $buffer.Length)) -gt 0) { $adoStream.Write($buffer, 0, $readBytes) } $adoStream.Position = 0 # 重置流指针到开头 # 用CDO.Message解析EML $cdoMsg = New-Object -ComObject CDO.Message $cdoMsg.DataSource.OpenObject($adoStream, "_Stream") # 提取From和To邮箱 [PSCustomObject]@{ FileName = $entry.Name From = $cdoMsg.From To = $cdoMsg.To } # 清理资源 $cdoMsg | Remove-Variable $adoStream.Close() $zipStream.Close() } $zipArchive.Dispose()
方案2:使用.NET原生类解析(推荐,无需COM对象)
用System.Net.Mail.MailMessage类直接读取Zip流,避免依赖COM组件,兼容性更好:
$zipPath = "你的ZIP文件路径" $zipArchive = [IO.Compression.ZipFile]::OpenRead($zipPath) foreach ($entry in $zipArchive.Entries) { if (-not $entry.Name.EndsWith(".eml", [StringComparison]::OrdinalIgnoreCase)) { continue } try { # 直接从Zip流创建MailMessage $zipStream = $entry.Open() $mailMsg = [System.Net.Mail.MailMessage]::new($zipStream) # 提取邮箱信息(MailMessage的From/To是MailAddress对象,可直接取Address属性) [PSCustomObject]@{ FileName = $entry.Name From = $mailMsg.From.Address To = $mailMsg.To | ForEach-Object { $_.Address } -join ", " } } catch { Write-Warning "解析文件 $($entry.Name) 失败: $_" } finally { $zipStream.Close() if ($mailMsg) { $mailMsg.Dispose() } } } $zipArchive.Dispose()
注意事项
- 方案2中,
.NET Core/.NET 5+环境下System.Net.Mail.MailMessage已被标记为过时,可改用System.Net.Mime.MailMessage(需确认PowerShell版本对应的.NET环境)。 - 处理大文件时,两种方案都是流处理,不会占用过多内存。
内容的提问来源于stack exchange,提问作者Samou Mc
相关产品推荐
相关产品推荐

