PowerShell内嵌C#调用Win10内置OCR程序集加载异常求助
PowerShell内嵌C#调用Windows内置OCR实现方案
加载失败根因
你遇到的dll加载错误和路径定位无关,核心原因有两点:
c:\Windows\System32\Windows.Media.Ocr.dll是WinRT原生系统组件,不是标准.NET程序集,直接通过Add-Type -ReferencedAssemblies指定dll路径加载的方式无法识别其格式,必然触发“尝试加载格式不正确的程序”错误- 原测试代码存在语法缺陷:异步方法返回值应为
Task<string>而非直接返回string,且缺少WinRT类型互操作、文件加载、识别结果处理的必要逻辑。
可直接运行的实现代码
该实现将OCR识别、BoundingRect坐标处理逻辑全部放在内嵌C#层执行,无跨语言调用开销,性能和纯C#实现一致,无需手动定位OCR相关dll路径:
# 加载WinRT互操作基础程序集 Add-Type -AssemblyName System.Runtime.WindowsRuntime $null = [Windows.Storage.StorageFile, Windows.Storage, ContentType = WindowsRuntime] $null = [Windows.Media.Ocr.OcrEngine, Windows.Foundation, ContentType = WindowsRuntime] $null = [Windows.Globalization.Language, Windows.Globalization, ContentType = WindowsRuntime] $null = [Windows.Graphics.Imaging.BitmapDecoder, Windows.Graphics.Imaging, ContentType = WindowsRuntime] # 内嵌C#实现完整OCR逻辑 Add-Type -Language CSharp -ReferencedAssemblies System.Runtime, System.Runtime.WindowsRuntime, System.Threading.Tasks @' using System; using System.Collections.Generic; using System.Threading.Tasks; using Windows.Storage; using Windows.Graphics.Imaging; using Windows.Media.Ocr; using Windows.Globalization; public static class Win10OCR { public class WordInfo { public string Text { get; set; } public double X { get; set; } public double Y { get; set; } public double Width { get; set; } public double Height { get; set; } } public class OcrOutput { public string FullText { get; set; } public List<WordInfo> Words { get; set; } } public async static Task<OcrOutput> Recognize(string imagePath, string langTag = "zh-CN") { var lang = new Language(langTag); var ocrEngine = OcrEngine.TryCreateFromLanguage(lang); if (ocrEngine == null) throw new InvalidOperationException($"系统未安装{langTag}对应的OCR语言包"); var imgFile = await StorageFile.GetFileFromPathAsync(imagePath); using (var stream = await imgFile.OpenAsync(FileAccessMode.Read)) { var decoder = await BitmapDecoder.CreateAsync(stream); var bitmap = await decoder.GetSoftwareBitmapAsync(); var rawResult = await ocrEngine.RecognizeAsync(bitmap); // C#层直接处理BoundingRect,无跨语言性能损耗 var wordList = new List<WordInfo>(); foreach (var line in rawResult.Lines) { foreach (var word in line.Words) { wordList.Add(new WordInfo { Text = word.Text, X = word.BoundingRect.X, Y = word.BoundingRect.Y, Width = word.BoundingRect.Width, Height = word.BoundingRect.Height }); } } return new OcrOutput { FullText = rawResult.Text, Words = wordList }; } } } '@ # 调用示例 $targetImg = Join-Path $PSScriptRoot "20000111-p001.jpg" # 英文识别传langTag为"en",异步方法必须等待执行完成再取结果 $ocrResult = [Win10OCR]::Recognize($targetImg, "en").GetAwaiter().GetResult() # 输出结果 Write-Host "识别全文:" $ocrResult.FullText Write-Host "`n单词坐标列表:" $ocrResult.Words | Format-Table
使用注意事项
- 运行环境要求:PowerShell 5.1及以上版本,Windows 10 1809+或Windows 11系统
- 切换识别语言时,修改
Recognize方法的langTag参数即可,前提是已在系统语言设置中安装对应语言的「光学字符识别」可选功能 - 禁止直接引用System32路径下的WinRT原生dll,所有WinRT类型通过
ContentType = WindowsRuntime标记从系统元数据缓存加载即可 - 所有结果遍历、坐标处理逻辑均在C#层完成,不存在PowerShell与C#跨环境遍历集合的性能损耗,执行速度和纯C#实现一致
内容的提问来源于stack exchange,提问作者Darin
相关产品推荐
相关产品推荐

