x86應用程式中的OcrInternals部署錯誤
IronTesseract.ReadScreenShot() 運行在 IronOCR 的 AdvancedScan 管道中,僅支持在 Windows x64 進程中使用。 從 x86 應用程式中調用它時會因 OcrInternals 部署錯誤失敗,即使安裝了 IronOcr.Extensions.AdvancedScan 套件也是如此。
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]
在 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);
}Dim ocr = New IronOcr.IronTesseract()
Using input = New IronOcr.OcrInput()
input.LoadImage("Step_1-5.jpg")
Dim result = ocr.ReadScreenShot(input)
Console.WriteLine(result.Text)
End UsingDim ocr = New IronOcr.IronTesseract()
Using input = New IronOcr.OcrInput()
input.LoadImage("Step_1-5.jpg")
Dim result = ocr.ReadScreenShot(input)
Console.WriteLine(result.Text)
End UsingAdvancedScan 所依賴的本地元件不支持在 x86 進程中。 需要安裝 IronOcr.Extensions.AdvancedScan,但這不會改變主機進程的位數,因此調用仍無法在 x86 下運行。
解決方案
選擇 1: 直接目標 x64
最直接的修復措施是將專案的平台目標切換到x64。在Visual Studio中:
- 右鍵點擊專案,然後選擇屬性。
- 打開建立選項卡。
- 將平台目標設置為x64。
- 取消選中首選32位。
- 重建並運行。
當主機進程以 x64 運行時,ReadScreenShot() 在支持的環境中執行。
選擇 2: 保持應用程式x86並調用x64輔助進程
當主應用程式必須保持x86時,只將OCR操作移入小型x64輔助進程並從現有應用程式調用。結構如下:
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
x86應用程式仍然不受影響,而AdvancedScan在它受支持的地方運行。
從x86應用程式調用輔助項
using ProcessStartInfo 啟動助手,並讀取其輸出:
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 NotInheritable Class OcrHelperClient
Private Sub New()
End Sub
Public Shared 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 = 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 ClassImports System
Imports System.Diagnostics
Imports System.IO
Public NotInheritable Class OcrHelperClient
Private Sub New()
End Sub
Public Shared 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 = 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 Class重新導向 StandardOutput 和 StandardError 允許調用者捕獲識別的文字,並從助手的退出程式碼中顯示任何錯誤。
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);Dim imagePath As String = "C:\Images\Step_1-5.jpg"
Dim text As String = OcrHelperClient.ReadScreenshotWithHelper(imagePath)
Console.WriteLine(text)Dim imagePath As String = "C:\Images\Step_1-5.jpg"
Dim text As String = OcrHelperClient.ReadScreenshotWithHelper(imagePath)
Console.WriteLine(text)建立x64輔助程式
將助手構建為引用 IronOcr 和 IronOcr.Extensions.AdvancedScan 的 x64 控制台應用程式。 它從第一個參數讀取圖像路徑,運行 OCR,並將結果寫入到 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 NamespaceImports 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不同的退出程式碼 (1, 2, 99) 允許調用應用程式區分缺少參數、缺少文件或意外異常。
製作使用說明
範例使用 stdout 以簡化操作。 對於生產,選擇適合您的建築的通信方法。 選擇包括:
- 標準輸出和標準錯誤。
- 臨時JSON文件。
- 命名管道。
- 本地HTTP端點。
- 託管x64 OCR操作的Windows服務。
對於小規模或偶爾呼叫:按需啟動輔助程式通常沒問題。對於大容量工作:長期運行的x64輔助服務比每個請求生成一個進程更高效。
除錯提示
當輔助方法不正常工作時,請通過這些檢查進行:
- 確認主應用程式確實需要保持 x86,並且
Ocr.Read()對截圖場景不足以滿足需求。 - 驗證
ReadScreenShot()直接從 x64 進程中運行時是否成功。 - 使用 平台目標:x64 構建助手專案,並確保 x86 應用程式從不調用
ReadScreenShot()本身。 - 在 x64 助手專案中安裝
IronOcr.Extensions.AdvancedScan。 - 確認傳遞給輔助程式的圖像路徑對輔助進程可達。
- 在程式碼、應用程式配置或
IRONOCR_LICENSE_KEY環境變數中配置 IronOCR 授權金鑰。
在發佈助手時,請複製整個構建輸出,而不僅僅是 .exe。 輸出文件夾必須包含所有引用的程式集和構建生成的本機運行時文件,否則輔助程式將遇到相同的部署錯誤。
Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。