OcrInternals Bereitstellungsfehler in x86-Anwendungen
IronTesseract.ReadScreenShot() läuft durch die AdvancedScan-Pipeline von IronOCR, die nur in einem Windows x64-Prozess unterstützt wird. Der Aufruf aus einer x86-Anwendung schlägt mit einem OcrInternals Bereitstellungsfehler fehl, selbst wenn das IronOcr.Extensions.AdvancedScan Paket installiert ist.
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]
Der Fehler tritt direkt beim Aufruf von ReadScreenShot() auf:
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
Die nativen AdvancedScan-Komponenten, von denen ReadScreenShot() abhängt, werden in einem x86-Prozess nicht unterstützt. Die Installation von IronOcr.Extensions.AdvancedScan ist erforderlich, aber sie ändert nicht die Bitness des Hostprozesses, sodass der Aufruf immer noch nicht unter x86 ausgeführt werden kann.
Lösung
Option 1: Direkter Zielsetzung auf x64
Der sauberste Fix ist es, das Plattformziel des Projekts auf x64 zu ändern. In Visual Studio:
- Klicken Sie mit der rechten Maustaste auf das Projekt und wählen Sie Eigenschaften.
- Öffnen Sie die Registerkarte Build.
- Setzen Sie Plattformziel auf x64.
- Deaktivieren Sie Bevorzugen 32-Bit.
- Erstellen und ausführen.
Mit einem als x64 laufenden Hostprozess wird ReadScreenShot() in einer unterstützten Umgebung ausgeführt.
Option 2: Die App x86 beibehalten und eine x64-Hilfsprozess aufrufen
Wenn die Hauptanwendung x86 bleiben muss, verschieben Sie nur den OCR-Vorgang in einen kleinen x64-Hilfsprozess und rufen Sie ihn von der bestehenden App aus auf. Die Struktur sieht so aus:
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
Die x86-Anwendung bleibt unberührt, während AdvancedScan dort ausgeführt wird, wo es unterstützt wird.
Aufruf des Helfers aus der x86-Anwendung
Starten Sie das Hilfsprogramm mit ProcessStartInfo und lesen Sie dessen Ausgabe:
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
Das Umleiten sowohl von StandardOutput als auch von StandardError ermöglicht es dem Anrufer, den erkannten Text zu erfassen und einen Fehler anhand des Exit-Codes des Hilfsprogramms zu erkennen.
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)
Aufbau des x64-Helfers
Erstellen Sie das Hilfsprogramm als x64-Konsolenanwendung, die IronOcr und IronOcr.Extensions.AdvancedScan referenziert. Es liest den Bildpfad aus dem ersten Argument, führt die OCR durch und schreibt das Ergebnis in 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
Unterschiedliche Exit-Codes (1, 2, 99) ermöglichen es der aufrufenden App, ein fehlendes Argument von einer fehlenden Datei oder einer unerwarteten Ausnahme zu unterscheiden.
Hinweise zur Produktion
Das Beispiel verwendet stdout zur Vereinfachung. Für die Produktion wählen Sie die Kommunikationsmethode, die zu Ihrer Architektur passt. Optionen umfassen:
- Standardausgabe und Standardfehler.
- Temporäre JSON-Dateien.
- Benannte Pipes.
- Ein lokaler HTTP-Endpunkt.
- Ein Windows-Dienst, der die x64-OCR-Operation hostet.
Für kleine oder gelegentliche Anrufe: das Starten des Helfers auf Anforderung ist normalerweise in Ordnung. Für hochvolumige Arbeitslasten: ein langlaufender x64-Hilfsdienst ist tendenziell effizienter als das Starten eines Prozesses pro Anforderung.
Debug-Tipps
Führen Sie diese Überprüfungen durch, wenn der Helferansatz sich falsch verhält:
- Bestätigen Sie, dass die Hauptanwendung tatsächlich im x86 bleiben muss und dass
Ocr.Read()für den Screenshot nicht ausreichend ist. - Überprüfen Sie, dass
ReadScreenShot()erfolgreich ist, wenn es direkt aus einem x64-Prozess ausgeführt wird. - Erstellen Sie das Hilfsprojekt mit Plattformziel: x64, und stellen Sie sicher, dass die x86-App niemals
ReadScreenShot()selbst aufruft. - Installieren Sie
IronOcr.Extensions.AdvancedScanim x64-Hilfsprojekt. - Prüfen Sie, dass der Bildpfad, der an den Helfer übergeben wird, vom Helferprozess erreicht werden kann.
- Konfigurieren Sie den IronOCR-Lizenzschlüssel im Code, in der App-Konfiguration oder der
IRONOCR_LICENSE_KEYUmgebungseinstellung.
Beim Veröffentlichen des Hilfsprogramms kopieren Sie die gesamte Bauausgabe, nicht nur den .exe. Der Ausgabefolder muss alle referenzierten Zusammenstellungen und die nativen Laufzeitedateien, die vom Build erzeugt werden, umfassen oder der Helfer trifft auf denselben Bereitstellungsfehler.

