Błąd wdrożenia OcrInternals w aplikacjach x86
IronTesseract.ReadScreenShot() działa przez zaawansowaną ścieżkę skanowania IronOCR, która jest obsługiwana tylko w procesie Windows x64. Wywołanie jej z aplikacji x86 kończy się błędem wdrożenia OcrInternals, nawet gdy pakiet IronOcr.Extensions.AdvancedScan jest zainstalowany.
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]
Niepowodzenie pojawia się na samym wywołaniu 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
Zaawansowane komponenty natywne, na których polega ReadScreenShot(), nie są obsługiwane w procesie x86. Instalacja IronOcr.Extensions.AdvancedScan jest wymagana, ale nie zmienia bitności procesu hosta, więc to wywołanie wciąż nie może działać w x86.
Rozwiązanie
Opcja 1: Bezpośredni cel x64
Najczystsze rozwiązanie to zmiana celu platformy projektu na x64. W Visual Studio:
- Kliknij prawym przyciskiem myszy projekt i wybierz Właściwości.
- Otwórz kartę Kompilacja.
- Ustaw Cel platformy na x64.
- Odznacz Preferowane 32-bitowe.
- Przebuduj i uruchom.
Z procesem hosta działającym jako x64, ReadScreenShot() działa w obsługiwanym środowisku.
Opcja 2: Utrzymaj app x86 i wywołuj proces pomocniczy x64
Kiedy główna aplikacja musi pozostać x86, przenieś tylko operację OCR do małego procesu pomocniczego x64 i wywołuj go z istniejącej aplikacji. Struktura wygląda na:
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
Aplikacja x86 pozostaje niezmieniona, podczas gdy AdvancedScan działa tam, gdzie jest obsługiwane.
Wywoływanie pomocnika z aplikacji x86
Uruchom pomocnika z ProcessStartInfo i odczytaj jego wyjście:
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
Przekierowanie zarówno StandardOutput, jak i StandardError pozwala wywołującemu uchwycić rozpoznany tekst i wyświetlić wszelkie niepowodzenie z kodu wyjścia pomocnika.
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)
Budowanie pomocnika x64
Zbuduj pomocnika jako aplikację konsolową x64, która odnosi się do IronOcr i IronOcr.Extensions.AdvancedScan. Odczytuje ścieżkę obrazu z pierwszego argumentu, uruchamia OCR i zapisuje wynik do 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
Odrębne kody wyjścia (1 2, 99) pozwalają wywołującej aplikacji rozróżniać brakujący argument od brakującego pliku lub nieoczekiwanego wyjątku.
Notatki do użytkowania produkcyjnego
Przykład wykorzystuje stdout dla uproszczenia. Dla produkcji wybierz metodę komunikacji, która pasuje do twojej architektury. Opcje obejmują:
- Standardowe wyjście i standardowy błąd.
- Tymczasowe pliki JSON.
- Nazwane potoki.
- Lokalny punkt końcowy HTTP.
- Usługa Windows hostująca operację OCR w x64.
Dla małych lub okazjonalnych wywołań: uruchamianie pomocnika na żądanie zazwyczaj jest w porządku. Dla dużych obciążeń roboczych: długotrwała usługa pomocnika x64 jest zazwyczaj bardziej efektywna niż tworzenie nowego procesu na każde żądanie.
Wskazówki dotyczące debugowania
Przeanalizuj te sprawdzenia, gdy podejście pomocnika działa źle:
- Potwierdź, że główna aplikacja faktycznie musi pozostać x86, i że
Ocr.Read()nie wystarcza dla scenariusza zrzutu ekranu. - Zweryfikuj
ReadScreenShot(), gdy uruchamiane bezpośrednio z procesu x64. - Zbuduj projekt pomocnika z Platforma docelowa: x64 i upewnij się, że aplikacja x86 nigdy nie wywołuje
ReadScreenShot()siebie. - Zainstaluj
IronOcr.Extensions.AdvancedScanw projekcie pomocnika x64. - Sprawdź, czy ścieżka obrazu przekazana do pomocnika jest osiągalna przez proces pomocnika.
- Skonfiguruj klucz licencyjny IronOCR w kodzie, konfiguracji aplikacji lub zmiennej środowiskowej
IRONOCR_LICENSE_KEY.
Podczas publikowania pomocnika skopiuj całą zawartość folderu build, nie tylko .exe. Folder wyjściowy musi zawierać wszystkie odwoływane zbiory i natywne pliki uruchomieniowe generowane podczas budowania, w przeciwnym razie pomocnik napotka ten sam błąd wdrożenia.

