Erro de Implantação do OcrInternals em Aplicativos x86
IronTesseract.ReadScreenShot() roda pelo pipeline AdvancedScan do IronOCR, que é suportado apenas em um processo Windows x64. Chamando-o de um aplicativo x86 falha com um erro de implantação OcrInternals, mesmo quando o pacote IronOcr.Extensions.AdvancedScan está instalado.
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]
A falha surge na própria chamada 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
Os componentes nativos AdvancedScan dos quais ReadScreenShot() depende não são suportados dentro de um processo x86. Instalar IronOcr.Extensions.AdvancedScan é necessário, mas isso não altera a arquitetura do processo host, então a chamada ainda não pode ser executada em x86.
Solução
Opção 1: Direcionar para x64 diretamente
A correção mais limpa é mudar o alvo de plataforma do projeto para x64. No Visual Studio:
- Clique com o botão direito no projeto e selecione Propriedades.
- Abra a aba Compilação.
- Defina Alvo da plataforma para x64.
- Desmarque Preferir 32 bits.
- Recompile e execute.
Com o processo host rodando como x64, ReadScreenShot() executa em um ambiente suportado.
Opção 2: Mantenha o aplicativo x86 e chame um processo auxiliar x64
Quando o aplicativo principal deve permanecer x86, mova apenas a operação OCR para um pequeno processo auxiliar x64 e chame-o do aplicativo existente. A estrutura se parece com isto:
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
O aplicativo x86 permanece inalterado enquanto o AdvancedScan roda onde é suportado.
Chamando o auxiliar do aplicativo x86
Inicie o auxiliar com ProcessStartInfo e leia sua saída:
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
Redirecionar tanto StandardOutput quanto StandardError permite que o chamador capture o texto reconhecido e apresente qualquer falha a partir do código de saída do auxiliar.
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)
Construindo o auxiliar x64
Construa o auxiliar como um aplicativo de console x64 que referencia IronOcr e IronOcr.Extensions.AdvancedScan. Lê o caminho da imagem do primeiro argumento, executa o OCR e grava o resultado em 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
Códigos de saída distintos (1, 2, 99) permitem que o aplicativo chamador diferencie entre um argumento ausente, um arquivo ausente ou uma exceção inesperada.
Notas para Uso em Produção
O exemplo usa stdout por simplicidade. Para produção, escolha o método de comunicação que se adequa à sua arquitetura. As opções incluem:
- Saída padrão e erro padrão.
- Arquivos JSON temporários.
- Pipes nomeados.
- Um endpoint HTTP local.
- Um serviço Windows hospedando a operação OCR x64.
Para chamadas pequenas ou ocasionais: lançar o auxiliar sob demanda geralmente está bem. Para cargas de trabalho de alto volume: um serviço auxiliar x64 de longa execução tende a ser mais eficiente do que iniciar um processo por solicitação.
Dicas de Depuração
Realize estas verificações quando a abordagem auxiliar se comportar mal:
- Confirme que o aplicativo principal realmente precisa permanecer x86, e que
Ocr.Read()não é suficiente para o cenário de captura de tela. - Verifique se
ReadScreenShot()é bem-sucedido quando executado diretamente de um processo x64. - Construa o projeto auxiliar com Plataforma alvo: x64, e certifique-se de que o aplicativo x86 nunca chame
ReadScreenShot()por si só. - Instale
IronOcr.Extensions.AdvancedScanno projeto auxiliar x64. - Verifique se o caminho da imagem passado para o auxiliar é acessível pelo processo auxiliar.
- Configure a chave de licença do IronOCR no código, configuração do aplicativo ou na variável de ambiente
IRONOCR_LICENSE_KEY.
Ao publicar o auxiliar, copie todo o resultado da construção, não apenas o .exe. A pasta de saída deve incluir todas as assemblies referenciadas e os arquivos de runtime nativo gerados pela construção, ou o auxiliar enfrentará o mesmo erro de implantação.

