在x86应用程序中OcrInternals部署错误

This article was translated from English: Does it need improvement?
Translated
View the article in English

IronTesseract.ReadScreenShot() 在IronOCR的AdvancedScan管道中运行,仅支持在Windows x64进程中。 从x86应用程序调用它会导致OcrInternals 部署错误,即使安装了IronOcr.Extensions.AdvancedScan 包。

Error while reading a screenshot, Error while deploying OcrInternals for IronOcr:
'Unable to locate 'OcrInternals' in
...\bin\Debug\runtimes\win-x86\native,
...\bin\Debug\runtimes\win.6.2-x86\native,
...\bin\Debug\runtimes\win.6-x86\native,
...\bin\Debug\,
...
nor in an embedded resource.'
Please install the NuGet Package 'IronOcr.Extension.AdvancedScan' when using IronOcr on Windows.
[Issue Code IRONOCR-OCRINTERNALS-DEPLOYMENT-ERROR-WIN]

故障显现在ReadScreenShot() 调用本身:

var ocr = new IronOcr.IronTesseract();
using (var input = new IronOcr.OcrInput())
{
    input.LoadImage("Step_1-5.jpg");
    var result = ocr.ReadScreenShot(input);
    Console.WriteLine(result.Text);
}
var ocr = new IronOcr.IronTesseract();
using (var input = new IronOcr.OcrInput())
{
    input.LoadImage("Step_1-5.jpg");
    var result = ocr.ReadScreenShot(input);
    Console.WriteLine(result.Text);
}
Imports IronOcr

Dim ocr As New IronTesseract()
Using input As New OcrInput()
    input.LoadImage("Step_1-5.jpg")
    Dim result = ocr.ReadScreenShot(input)
    Console.WriteLine(result.Text)
End Using
$vbLabelText   $csharpLabel

AdvancedScan本机组件依赖的ReadScreenShot() 不支持在x86进程中。 需要安装IronOcr.Extensions.AdvancedScan,但这不会更改主机进程的位数,因此调用仍不能在x86下运行。

([(安装AdvancedScan并不能使ReadScreenShot()在x86进程中工作。 调用它的进程必须以x64运行。)

解决方案

选项1:直接定位x64

最干净的解决方法是将项目的平台目标切换为x64。在Visual Studio中:

  1. 右键点击项目并选择属性
  2. 打开生成选项卡。
  3. 设置平台目标x64
  4. 取消勾选首选32位
  5. 重新构建并运行。

当主机进程以x64运行时,ReadScreenShot() 在支持的环境中执行。

选项2:保持应用程序x86并调用x64帮助进程

当主应用程序必须保持x86时,仅将OCR操作移至一个小型x64帮助进程并从现有应用程序调用结构如下:

MainWinForms.x86
  - .NET Framework Windows Forms app
  - Platform target: x86
  - Does not run ReadScreenShot() directly
  - Calls the x64 helper process
OcrHelper.x64
  - .NET Framework Console app
  - Platform target: x64
  - References IronOCR
  - References IronOcr.Extensions.AdvancedScan
  - Runs Ocr.ReadScreenShot()
  - Returns the OCR result to the main app

x86应用程序保持不变,而AdvancedScan在其受支持的地方运行。

从x86应用程序调用帮助进程

使用ProcessStartInfo 启动助手并读取其输出:

using System;
using System.Diagnostics;
using System.IO;
public static class OcrHelperClient
{
    public static string ReadScreenshotWithHelper(string imagePath)
    {
        string helperExePath = Path.Combine(
            AppDomain.CurrentDomain.BaseDirectory,
            "OcrHelper.x64",
            "OcrHelper.x64.exe"
        );
        if (!File.Exists(helperExePath))
        {
            throw new FileNotFoundException("The OCR helper executable was not found.", helperExePath);
        }
        var startInfo = new ProcessStartInfo
        {
            FileName = helperExePath,
            Arguments = "\"" + imagePath + "\"",
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        };
        using (var process = new Process())
        {
            process.StartInfo = startInfo;
            process.Start();
            string output = process.StandardOutput.ReadToEnd();
            string error = process.StandardError.ReadToEnd();
            process.WaitForExit();
            if (process.ExitCode != 0)
            {
                throw new Exception("OCR helper failed: " + error);
            }
            return output;
        }
    }
}
using System;
using System.Diagnostics;
using System.IO;
public static class OcrHelperClient
{
    public static string ReadScreenshotWithHelper(string imagePath)
    {
        string helperExePath = Path.Combine(
            AppDomain.CurrentDomain.BaseDirectory,
            "OcrHelper.x64",
            "OcrHelper.x64.exe"
        );
        if (!File.Exists(helperExePath))
        {
            throw new FileNotFoundException("The OCR helper executable was not found.", helperExePath);
        }
        var startInfo = new ProcessStartInfo
        {
            FileName = helperExePath,
            Arguments = "\"" + imagePath + "\"",
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        };
        using (var process = new Process())
        {
            process.StartInfo = startInfo;
            process.Start();
            string output = process.StandardOutput.ReadToEnd();
            string error = process.StandardError.ReadToEnd();
            process.WaitForExit();
            if (process.ExitCode != 0)
            {
                throw new Exception("OCR helper failed: " + error);
            }
            return output;
        }
    }
}
Imports System
Imports System.Diagnostics
Imports System.IO

Public Module OcrHelperClient
    Public Function ReadScreenshotWithHelper(imagePath As String) As String
        Dim helperExePath As String = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "OcrHelper.x64", "OcrHelper.x64.exe")
        If Not File.Exists(helperExePath) Then
            Throw New FileNotFoundException("The OCR helper executable was not found.", helperExePath)
        End If

        Dim startInfo As New ProcessStartInfo With {
            .FileName = helperExePath,
            .Arguments = """" & imagePath & """",
            .UseShellExecute = False,
            .RedirectStandardOutput = True,
            .RedirectStandardError = True,
            .CreateNoWindow = True
        }

        Using process As New Process()
            process.StartInfo = startInfo
            process.Start()
            Dim output As String = process.StandardOutput.ReadToEnd()
            Dim error As String = process.StandardError.ReadToEnd()
            process.WaitForExit()

            If process.ExitCode <> 0 Then
                Throw New Exception("OCR helper failed: " & error)
            End If

            Return output
        End Using
    End Function
End Module
$vbLabelText   $csharpLabel

重定向StandardOutputStandardError 允许调用者捕获识别文本并显示任何从助手的退出代码中出现的故障。

string imagePath = @"C:\Images\Step_1-5.jpg";
string text = OcrHelperClient.ReadScreenshotWithHelper(imagePath);
Console.WriteLine(text);
string imagePath = @"C:\Images\Step_1-5.jpg";
string text = OcrHelperClient.ReadScreenshotWithHelper(imagePath);
Console.WriteLine(text);
Imports System

Dim imagePath As String = "C:\Images\Step_1-5.jpg"
Dim text As String = OcrHelperClient.ReadScreenshotWithHelper(imagePath)
Console.WriteLine(text)
$vbLabelText   $csharpLabel

构建x64帮助进程

将助手构建为引用IronOcrIronOcr.Extensions.AdvancedScan 的x64控制台应用程序。 它从第一个参数读取图像路径,运行OCR,并将结果写入stdout

using System;
using System.IO;
using IronOcr;
namespace OcrHelper.x64
{
    internal static class Program
    {
        private static int Main(string[] args)
        {
            try
            {
                if (args.Length == 0)
                {
                    Console.Error.WriteLine("Missing image path argument.");
                    return 1;
                }
                string imagePath = args[0];
                if (!File.Exists(imagePath))
                {
                    Console.Error.WriteLine("Image file was not found: " + imagePath);
                    return 2;
                }
                string licenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY");
                if (!string.IsNullOrWhiteSpace(licenseKey))
                {
                    License.LicenseKey = licenseKey;
                }
                var ocr = new IronTesseract();
                using (var input = new OcrInput())
                {
                    input.LoadImage(imagePath);
                    var result = ocr.ReadScreenShot(input);
                    Console.WriteLine(result.Text);
                }
                return 0;
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.ToString());
                return 99;
            }
        }
    }
}
using System;
using System.IO;
using IronOcr;
namespace OcrHelper.x64
{
    internal static class Program
    {
        private static int Main(string[] args)
        {
            try
            {
                if (args.Length == 0)
                {
                    Console.Error.WriteLine("Missing image path argument.");
                    return 1;
                }
                string imagePath = args[0];
                if (!File.Exists(imagePath))
                {
                    Console.Error.WriteLine("Image file was not found: " + imagePath);
                    return 2;
                }
                string licenseKey = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY");
                if (!string.IsNullOrWhiteSpace(licenseKey))
                {
                    License.LicenseKey = licenseKey;
                }
                var ocr = new IronTesseract();
                using (var input = new OcrInput())
                {
                    input.LoadImage(imagePath);
                    var result = ocr.ReadScreenShot(input);
                    Console.WriteLine(result.Text);
                }
                return 0;
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.ToString());
                return 99;
            }
        }
    }
}
Imports System
Imports System.IO
Imports IronOcr

Namespace OcrHelper.x64
    Friend Module Program
        Private Function Main(args As String()) As Integer
            Try
                If args.Length = 0 Then
                    Console.Error.WriteLine("Missing image path argument.")
                    Return 1
                End If

                Dim imagePath As String = args(0)
                If Not File.Exists(imagePath) Then
                    Console.Error.WriteLine("Image file was not found: " & imagePath)
                    Return 2
                End If

                Dim licenseKey As String = Environment.GetEnvironmentVariable("IRONOCR_LICENSE_KEY")
                If Not String.IsNullOrWhiteSpace(licenseKey) Then
                    License.LicenseKey = licenseKey
                End If

                Dim ocr As New IronTesseract()
                Using input As New OcrInput()
                    input.LoadImage(imagePath)
                    Dim result = ocr.ReadScreenShot(input)
                    Console.WriteLine(result.Text)
                End Using

                Return 0
            Catch ex As Exception
                Console.Error.WriteLine(ex.ToString())
                Return 99
            End Try
        End Function
    End Module
End Namespace
$vbLabelText   $csharpLabel

不同的退出代码(1, 2, 99)让调用应用程序区分缺失参数、缺失文件或意外异常。

生产使用说明

样例使用stdout 简化。 对于生产,请选择适合您架构的通信方法。 选项包括:

  • 标准输出和标准错误。
  • 临时JSON文件。
  • 命名管道。
  • 本地HTTP端点。
  • 托管x64 OCR操作的Windows服务。

对于小型或偶尔的调用:按需启动帮助进程通常很好。对于大容量工作负载:长时间运行的x64帮助服务往往比每次请求生成一个进程更高效。

调试提示

当帮助进程方法运行不正常时,请通过以下检查:

  • 确认主应用程序确实需要保持x86,并且Ocr.Read() 对屏幕截图场景是不够的。
  • 验证ReadScreenShot() 在直接从x64进程运行时成功。
  • 使用平台目标:x64构建助手项目,并确保x86应用程序从不调用ReadScreenShot() 本身。
  • 在x64助手项目中安装IronOcr.Extensions.AdvancedScan
  • 检查传递给帮助进程的图像路径是否可以被帮助进程访问。
  • 在代码、应用程序配置或IRONOCR_LICENSE_KEY 环境变量中配置IronOCR许可证密钥。

发布助手时,复制整个构建输出,而不仅仅是.exe。 输出文件夹必须包括所有引用的程序集和构建生成的本地运行时文件,否则帮助进程将遇到相同的部署错误。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

准备开始了吗?
Nuget 下载 6,136,090 | 版本: 2026.7 刚刚发布
Still Scrolling Icon

还在滚动吗?

想快速获得证据? PM > Install-Package IronOcr
运行示例 观看您的图像变成可搜索文本。