OcrInternals Deployment Error in x86 Applications

IronTesseract.ReadScreenShot() runs through IronOCR's AdvancedScan pipeline, which is supported only in a Windows x64 process. Calling it from an x86 application fails with an OcrInternals deployment error, even when the IronOcr.Extensions.AdvancedScan package is installed.

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]

The failure surfaces on the ReadScreenShot() call itself:

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

The AdvancedScan native components that ReadScreenShot() depends on are not supported inside an x86 process. Installing IronOcr.Extensions.AdvancedScan is required, but it does not change the bitness of the host process, so the call still cannot run under x86.

CautionInstalling AdvancedScan does not make ReadScreenShot() work in an x86 process. The process that calls it must run as x64.

Solution

Option 1: Target x64 directly

The cleanest fix is to switch the project's platform target to x64. In Visual Studio:

  1. Right-click the project and select Properties.
  2. Open the Build tab.
  3. Set Platform target to x64.
  4. Uncheck Prefer 32-bit.
  5. Rebuild and run.

With the host process running as x64, ReadScreenShot() executes in a supported environment.

Option 2: Keep the app x86 and call an x64 helper process

When the main application must stay x86, move only the OCR operation into a small x64 helper process and call it from the existing app. The structure looks like this:

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

The x86 application stays untouched while AdvancedScan runs where it is supported.

Calling the helper from the x86 application

Launch the helper with ProcessStartInfo and read its 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;
        }
    }
}
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

Redirecting both StandardOutput and StandardError lets the caller capture the recognized text and surface any failure from the helper's exit code.

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

Building the x64 helper

Build the helper as an x64 console app that references IronOcr and IronOcr.Extensions.AdvancedScan. It reads the image path from the first argument, runs the OCR, and writes the result to 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

Distinct exit codes (1, 2, 99) let the calling app tell a missing argument from a missing file or an unexpected exception.

Notes for Production Use

The sample uses stdout for simplicity. For production, pick the communication method that fits your architecture. Options include:

  • Standard output and standard error.
  • Temporary JSON files.
  • Named pipes.
  • A local HTTP endpoint.
  • A Windows Service hosting the x64 OCR operation.

For small or occasional calls: launching the helper on demand is usually fine. For high-volume workloads: a long-running x64 helper service tends to be more efficient than spawning a process per request.

Debug Tips

Work through these checks when the helper approach misbehaves:

  • Confirm the main application genuinely needs to stay x86, and that Ocr.Read() is not sufficient for the screenshot scenario.
  • Verify ReadScreenShot() succeeds when run directly from an x64 process.
  • Build the helper project with Platform target: x64, and make sure the x86 app never calls ReadScreenShot() itself.
  • Install IronOcr.Extensions.AdvancedScan in the x64 helper project.
  • Check that the image path passed to the helper is reachable by the helper process.
  • Configure the IronOCR license key in code, app config, or the IRONOCR_LICENSE_KEY environment variable.

When publishing the helper, copy the entire build output, not just the .exe. The output folder must include all referenced assemblies and the native runtime files generated by the build, or the helper will hit the same deployment error.

Curtis Chau
Technical Writer

Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.

...

Read More
Ready to Get Started?
Nuget Downloads 6,106,091 | Version: 2026.7 just released
Still Scrolling Icon

Still Scrolling?

Want proof fast? PM > Install-Package IronOcr
run a sample watch your image become searchable text.