# 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.
```txt
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:
```csharp
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);
}
```
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.
[[e:(Installing 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:
```txt
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:
```csharp
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;
}
}
}
```
Redirecting both `StandardOutput` and `StandardError` lets the caller capture the recognized text and surface any failure from the helper's exit code.
```csharp
string imagePath = @"C:\Images\Step_1-5.jpg";
string text = OcrHelperClient.ReadScreenshotWithHelper(imagePath);
Console.WriteLine(text);
```
#### 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`:
```csharp
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;
}
}
}
}
```
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.
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]
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]
Text
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);
}
C#
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.
Caution: Installing 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:
Right-click the project and select Properties.
Open the Build tab.
Set Platform target to x64.
Uncheck Prefer 32-bit.
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 processOcrHelper.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
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
Text
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 stringReadScreenshotWithHelper(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;
}
}
}
C#
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);
C#
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 intMain(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;
}
}
}
}
C#
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 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.