Erreur de déploiement d'OcrInternals dans les applications x86
IronTesseract.ReadScreenShot() fonctionne via le pipeline AdvancedScan d'IronOCR, qui est pris en charge uniquement dans un processus Windows x64. L'appeler à partir d'une application x86 échoue avec une erreur de déploiement OcrInternals, même lorsque le package IronOcr.Extensions.AdvancedScan est installé.
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]
L'échec se manifeste lors de l'appel ReadScreenShot() lui-même :
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
Les composants natifs AdvancedScan dont dépend ReadScreenShot() ne sont pas pris en charge dans un processus x86. L'installation de IronOcr.Extensions.AdvancedScan est nécessaire, mais elle ne change pas l'architecture du processus hôte, donc l'appel ne peut toujours pas s'exécuter en x86.
Solution
Option 1 : Cibler x64 directement
La solution la plus propre est de passer la cible de la plateforme du projet à x64. Dans Visual Studio :
- Faites un clic droit sur le projet et sélectionnez Propriétés.
- Ouvrez l'onglet Build.
- Définissez Plateforme cible sur x64.
- Décochez Préférer 32 bits.
- Recomposez et exécutez.
Avec le processus hôte s'exécutant en x64, ReadScreenShot() s'exécute dans un environnement pris en charge.
Option 2 : Conserver l'application x86 et appeler un processus d'assistance x64
Lorsque l'application principale doit rester x86, déplacez uniquement l'opération OCR dans un petit processus d'assistance x64 et appelez-le depuis l'application existante. La structure ressemble à ceci :
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
L'application x86 reste inchangée tandis qu'AdvancedScan s'exécute là où elle est prise en charge.
Appeler l'assistant depuis l'application x86
Lancez l'assistant avec ProcessStartInfo et lisez sa sortie :
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
Rediriger à la fois StandardOutput et StandardError permet à l'appelant de capturer le texte reconnu et de signaler toute défaillance à partir du code de sortie de l'assistant.
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)
Construire l'assistant x64
Construisez l'assistant comme une application console x64 qui référence IronOcr et IronOcr.Extensions.AdvancedScan. Il lit le chemin de l'image à partir du premier argument, exécute l'OCR, et écrit le résultat dans 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
Des codes de sortie distincts (1, 2, 99) permettent à l'application appelante de distinguer un argument manquant d'un fichier manquant ou d'une exception inattendue.
Notes pour l'utilisation en production
L'exemple utilise stdout pour la simplicité. Pour la production, choisissez la méthode de communication qui convient à votre architecture. Les options incluent :
- La sortie standard et l'erreur standard.
- Les fichiers JSON temporaires.
- Les canaux nommés.
- Un point de terminaison HTTP local.
- Un service Windows hébergeant l'opération OCR x64.
Pour les appels petits ou occasionnels : lancer l'assistant à la demande est généralement correct. Pour les charges lourdes : un service assistant x64 de longue durée tend à être plus efficace que de lancer un processus par requête.
Conseils de débogage
Travaillez à travers ces vérifications lorsque l'approche de l'assistant se comporte mal :
- Confirmez que l'application principale a vraiment besoin de rester en x86, et que
Ocr.Read()n'est pas suffisant pour le scénario de capture d'écran. - Vérifiez que
ReadScreenShot()réussit lorsqu'il est exécuté directement à partir d'un processus x64. - Construisez le projet d'assistant avec Plateforme cible : x64, et assurez-vous que l'application x86 n'appelle jamais
ReadScreenShot()elle-même. - Installez
IronOcr.Extensions.AdvancedScandans le projet d'assistant x64. - Vérifiez que le chemin de l'image passé à l'assistant est accessible par le processus assistant.
- Configurez la clé de licence IronOCR dans le code, la config de l'app ou la variable d'environnement
IRONOCR_LICENSE_KEY.
Lors de la publication de l'assistant, copiez l'intégralité du résultat de la construction, pas seulement .exe. Le dossier de sortie doit inclure tous les assemblies référencés et les fichiers d'exécution natifs générés par la construction, ou l'assistant rencontrera la même erreur de déploiement.

