Erreur de déploiement d'OcrInternals dans les applications x86

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

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
$vbLabelText   $csharpLabel

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.

PrudenceL'installation d'AdvancedScan ne permet pas ReadScreenShot() de fonctionner dans un processus x86. Le processus qui l'appelle doit fonctionner en x64.

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 :

  1. Faites un clic droit sur le projet et sélectionnez Propriétés.
  2. Ouvrez l'onglet Build.
  3. Définissez Plateforme cible sur x64.
  4. Décochez Préférer 32 bits.
  5. 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
$vbLabelText   $csharpLabel

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)
$vbLabelText   $csharpLabel

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
$vbLabelText   $csharpLabel

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.AdvancedScan dans 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.

Curtis Chau
Rédacteur technique

Curtis Chau détient un baccalauréat en informatique (Université de Carleton) et se spécialise dans le développement front-end avec expertise en Node.js, TypeScript, JavaScript et React. Passionné par la création d'interfaces utilisateur intuitives et esthétiquement plaisantes, Curtis aime travailler avec des frameworks modernes ...

Lire la suite
Prêt à commencer?
Nuget Téléchargements 6,136,090 | Version : 2026.7 vient de sortir
Still Scrolling Icon

Vous faites encore défiler ?

Vous voulez une preuve rapidement ? PM > Install-Package IronOcr
lancez un échantillon regardez votre image se transformer en texte consultable.