为 pdf 操作创建自定义模块
create custom module for pdf manipulation
我想创建自定义 Kofax 模块。当涉及到批处理时,扫描的文档会转换为 PDF 文件。我想获取这些 PDF 文件,对其进行操作(向 PDF 文档添加自定义页脚)并将它们交还给 Kofax。
到目前为止我所知道的:
- 创建 Kofax 导出脚本
- 向 Kofax 添加自定义模块
我有 APIRef.chm (Kofax.Capture.SDK.CustomModule) 和 CMSplit 作为示例项目。不幸的是我很难进入它。是否有任何资源逐步展示如何进入自定义模块开发?
所以我知道IBatch
接口代表一个选择的批次,IBatchCollection
代表所有批次的集合。
我只想知道如何设置 "Hello World" 示例并可以将我的代码添加到其中,我认为我什至不需要 WinForms 应用程序,因为我只需要操作 PDF 文件和就是这样...
Kofax 将批处理公开为 XML,而 DBLite
基本上是所述 XML 的包装器。该结构在 AcBatch.htm 和 AcDocs.htm 中进行了解释(可在 CaptureSV 目录下找到)。这是基本思想(仅显示文档):
- AscentCaptureRuntime
- 批量
- 文件
- 文档
单个文档本身具有子元素(例如页面)和多个属性(例如 Confidence
、FormTypeName
和 PDFGenerationFileName
。这就是你想要的。以下是向下导航文档集合的方法,将文件名存储在名为 pdfFileName
:
的变量中
IACDataElement runtime = activeBatch.ExtractRuntimeACDataElement(0);
IACDataElement batch = runtime.FindChildElementByName("Batch");
var documents = batch.FindChildElementByName("Documents").FindChildElementsByName("Document");
for (int i = 0; i < documents.Count; i++)
{
// 1-based index in kofax
var pdfFileName = documents[i + 1]["PDFGenerationFileName"];
}
就我个人而言,我不喜欢这种结构,所以我为他们的包装器创建了自己的包装器,但这取决于您。
就自定义模块本身而言,交付的样品已经是一个不错的开始。基本上,如果用户手动启动模块,您将有一个显示的基本表单——如果工作在后面发生,这完全是可选的,最好是 Windows 服务。我喜欢从控制台应用程序开始,只在需要时添加表单。在这里,我将按如下方式启动表单,或启动服务。请注意,我有不同的分支,以防用户想要将我的自定义模块安装为服务:
else if (Environment.UserInteractive)
{
// run as module
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new RuntimeForm(args));
}
else
{
// run as service
ServiceBase.Run(new CustomModuleService());
}
}
运行时本身只是将您登录到 Kofax Capture、注册事件处理程序并逐批处理:
// login to KC
cm = new CustomModule();
cm.Login("", "");
// add progress event handlers
cm.BatchOpened += Cm_BatchOpened;
cm.BatchClosed += Cm_BatchClosed;
cm.DocumentOpened += Cm_DocumentOpened;
cm.DocumentClosed += Cm_DocumentClosed;
cm.ErrorOccured += Cm_ErrorOccured;
// process in background thread so that the form does not freeze
worker = new BackgroundWorker();
worker.DoWork += (s, a) => Process();
worker.RunWorkerAsync();
然后,您的 CM 获取下一批。这可以使用 Kofax 的批处理通知服务,也可以基于计时器。对于前者,只需处理会话对象的BatchAvailable
事件:
session.BatchAvailable += Session_BatchAvailable;
对于后者,定义一个计时器 - 最好具有可配置的轮询间隔:
pollTimer.Interval = pollIntervalSeconds * 1000;
pollTimer.Elapsed += PollTimer_Elapsed;
pollTimer.Enabled = true;
当计时器到时,您可以执行以下操作:
private void PollTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
mutex.WaitOne();
ProcessBatches();
mutex.ReleaseMutex();
}
既然我意识到你的问题是关于如何创建一个通用的自定义模块,请允许我添加另一个答案。从 C# 控制台应用程序开始。
添加所需的程序集
自定义模块需要以下程序集。它们都位于 KC 的二进制文件文件夹中(默认情况下 C:\Program Files (x86)\Kofax\CaptureSS\ServLib\Bin
在服务器上)。
设置部分
为设置添加新的 User Control
和 Windows Form
。这完全是可选的 - CM 甚至可能没有设置表单,但我建议无论如何添加它。用户控件是最重要的部分,这里 - 它将在 KC Administration 中添加菜单条目,并初始化表单本身:
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ISetupForm
{
[DispId(1)]
AdminApplication Application { set; }
[DispId(2)]
void ActionEvent(int EventNumber, object Argument, out int Cancel);
}
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Quipu.KC.CM.Setup")]
public class SetupUserControl : UserControl, ISetupForm
{
private AdminApplication adminApplication;
public AdminApplication Application
{
set
{
value.AddMenu("Quipu.KC.CM.Setup", "Quipu.KC.CM - Setup", "BatchClass");
adminApplication = value;
}
}
public void ActionEvent(int EventNumber, object Argument, out int Cancel)
{
Cancel = 0;
if ((KfxOcxEvent)EventNumber == KfxOcxEvent.KfxOcxEventMenuClicked && (string)Argument == "Quipu.KC.CM.Setup")
{
SetupForm form = new SetupForm();
form.ShowDialog(adminApplication.ActiveBatchClass);
}
}
}
运行时部分
由于我是从控制台应用程序开始的,所以我可以继续将所有逻辑放入 Program.cs
。请注意,这仅用于演示目的,我建议稍后添加特定的 类 和表格。下面的示例登录到 Kofax Capture,抓取下一个可用的批次,然后只输出其名称。
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) => KcAssemblyResolver.Resolve(eventArgs);
Run(args);
return;
}
static void Run(string[] args)
{
// start processing here
// todo encapsulate this to a separate class!
// login to KC
var login = new Login();
login.EnableSecurityBoost = true;
login.Login();
login.ApplicationName = "Quipu.KC.CM";
login.Version = "1.0";
login.ValidateUser("Quipu.KC.CM.exe", false, "", "");
var session = login.RuntimeSession;
// todo add timer-based polling here (note: mutex!)
var activeBatch = session.NextBatchGet(login.ProcessID);
Console.WriteLine(activeBatch.Name);
activeBatch.BatchClose(
KfxDbState.KfxDbBatchReady,
KfxDbQueue.KfxDbQueueNext,
0,
"");
session.Dispose();
login.Logout();
}
}
注册、COM 可见性等
注册自定义模块是通过 RegAsm.exe
完成的,最好借助 AEX 文件。这是一个示例 - 请参阅文档以获取更多详细信息和所有可用设置。
[Modules]
Minimal CM
[Minimal CM]
RuntimeProgram=Quipu/CM/Quipu.KC.CM/Quipu.KC.CM.exe
ModuleID=Quipu.KC.CM.exe
Description=Minimal Template for a Custom Module in C#
Version=1.0
SupportsTableFields=True
SupportsNonImageFiles=True
SetupProgram=Minimal CM Setup
[Setup Programs]
Minimal CM Setup
[Minimal CM Setup]
Visible=0
OCXFile=Quipu/CM/Quipu.KC.CM/Quipu.KC.CM.exe
ProgID=Quipu.KC.CM.Setup
最后但同样重要的是,确保您的程序集是 COM 可见的:
我把整个代码都放在 GitHub 上了,请随意分叉。希望对你有帮助。
我想创建自定义 Kofax 模块。当涉及到批处理时,扫描的文档会转换为 PDF 文件。我想获取这些 PDF 文件,对其进行操作(向 PDF 文档添加自定义页脚)并将它们交还给 Kofax。
到目前为止我所知道的:
- 创建 Kofax 导出脚本
- 向 Kofax 添加自定义模块
我有 APIRef.chm (Kofax.Capture.SDK.CustomModule) 和 CMSplit 作为示例项目。不幸的是我很难进入它。是否有任何资源逐步展示如何进入自定义模块开发?
所以我知道IBatch
接口代表一个选择的批次,IBatchCollection
代表所有批次的集合。
我只想知道如何设置 "Hello World" 示例并可以将我的代码添加到其中,我认为我什至不需要 WinForms 应用程序,因为我只需要操作 PDF 文件和就是这样...
Kofax 将批处理公开为 XML,而 DBLite
基本上是所述 XML 的包装器。该结构在 AcBatch.htm 和 AcDocs.htm 中进行了解释(可在 CaptureSV 目录下找到)。这是基本思想(仅显示文档):
- AscentCaptureRuntime
- 批量
- 文件
- 文档
- 文件
- 批量
单个文档本身具有子元素(例如页面)和多个属性(例如 Confidence
、FormTypeName
和 PDFGenerationFileName
。这就是你想要的。以下是向下导航文档集合的方法,将文件名存储在名为 pdfFileName
:
IACDataElement runtime = activeBatch.ExtractRuntimeACDataElement(0);
IACDataElement batch = runtime.FindChildElementByName("Batch");
var documents = batch.FindChildElementByName("Documents").FindChildElementsByName("Document");
for (int i = 0; i < documents.Count; i++)
{
// 1-based index in kofax
var pdfFileName = documents[i + 1]["PDFGenerationFileName"];
}
就我个人而言,我不喜欢这种结构,所以我为他们的包装器创建了自己的包装器,但这取决于您。
就自定义模块本身而言,交付的样品已经是一个不错的开始。基本上,如果用户手动启动模块,您将有一个显示的基本表单——如果工作在后面发生,这完全是可选的,最好是 Windows 服务。我喜欢从控制台应用程序开始,只在需要时添加表单。在这里,我将按如下方式启动表单,或启动服务。请注意,我有不同的分支,以防用户想要将我的自定义模块安装为服务:
else if (Environment.UserInteractive)
{
// run as module
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new RuntimeForm(args));
}
else
{
// run as service
ServiceBase.Run(new CustomModuleService());
}
}
运行时本身只是将您登录到 Kofax Capture、注册事件处理程序并逐批处理:
// login to KC
cm = new CustomModule();
cm.Login("", "");
// add progress event handlers
cm.BatchOpened += Cm_BatchOpened;
cm.BatchClosed += Cm_BatchClosed;
cm.DocumentOpened += Cm_DocumentOpened;
cm.DocumentClosed += Cm_DocumentClosed;
cm.ErrorOccured += Cm_ErrorOccured;
// process in background thread so that the form does not freeze
worker = new BackgroundWorker();
worker.DoWork += (s, a) => Process();
worker.RunWorkerAsync();
然后,您的 CM 获取下一批。这可以使用 Kofax 的批处理通知服务,也可以基于计时器。对于前者,只需处理会话对象的BatchAvailable
事件:
session.BatchAvailable += Session_BatchAvailable;
对于后者,定义一个计时器 - 最好具有可配置的轮询间隔:
pollTimer.Interval = pollIntervalSeconds * 1000;
pollTimer.Elapsed += PollTimer_Elapsed;
pollTimer.Enabled = true;
当计时器到时,您可以执行以下操作:
private void PollTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
mutex.WaitOne();
ProcessBatches();
mutex.ReleaseMutex();
}
既然我意识到你的问题是关于如何创建一个通用的自定义模块,请允许我添加另一个答案。从 C# 控制台应用程序开始。
添加所需的程序集
自定义模块需要以下程序集。它们都位于 KC 的二进制文件文件夹中(默认情况下 C:\Program Files (x86)\Kofax\CaptureSS\ServLib\Bin
在服务器上)。
设置部分
为设置添加新的 User Control
和 Windows Form
。这完全是可选的 - CM 甚至可能没有设置表单,但我建议无论如何添加它。用户控件是最重要的部分,这里 - 它将在 KC Administration 中添加菜单条目,并初始化表单本身:
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ISetupForm
{
[DispId(1)]
AdminApplication Application { set; }
[DispId(2)]
void ActionEvent(int EventNumber, object Argument, out int Cancel);
}
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Quipu.KC.CM.Setup")]
public class SetupUserControl : UserControl, ISetupForm
{
private AdminApplication adminApplication;
public AdminApplication Application
{
set
{
value.AddMenu("Quipu.KC.CM.Setup", "Quipu.KC.CM - Setup", "BatchClass");
adminApplication = value;
}
}
public void ActionEvent(int EventNumber, object Argument, out int Cancel)
{
Cancel = 0;
if ((KfxOcxEvent)EventNumber == KfxOcxEvent.KfxOcxEventMenuClicked && (string)Argument == "Quipu.KC.CM.Setup")
{
SetupForm form = new SetupForm();
form.ShowDialog(adminApplication.ActiveBatchClass);
}
}
}
运行时部分
由于我是从控制台应用程序开始的,所以我可以继续将所有逻辑放入 Program.cs
。请注意,这仅用于演示目的,我建议稍后添加特定的 类 和表格。下面的示例登录到 Kofax Capture,抓取下一个可用的批次,然后只输出其名称。
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) => KcAssemblyResolver.Resolve(eventArgs);
Run(args);
return;
}
static void Run(string[] args)
{
// start processing here
// todo encapsulate this to a separate class!
// login to KC
var login = new Login();
login.EnableSecurityBoost = true;
login.Login();
login.ApplicationName = "Quipu.KC.CM";
login.Version = "1.0";
login.ValidateUser("Quipu.KC.CM.exe", false, "", "");
var session = login.RuntimeSession;
// todo add timer-based polling here (note: mutex!)
var activeBatch = session.NextBatchGet(login.ProcessID);
Console.WriteLine(activeBatch.Name);
activeBatch.BatchClose(
KfxDbState.KfxDbBatchReady,
KfxDbQueue.KfxDbQueueNext,
0,
"");
session.Dispose();
login.Logout();
}
}
注册、COM 可见性等
注册自定义模块是通过 RegAsm.exe
完成的,最好借助 AEX 文件。这是一个示例 - 请参阅文档以获取更多详细信息和所有可用设置。
[Modules]
Minimal CM
[Minimal CM]
RuntimeProgram=Quipu/CM/Quipu.KC.CM/Quipu.KC.CM.exe
ModuleID=Quipu.KC.CM.exe
Description=Minimal Template for a Custom Module in C#
Version=1.0
SupportsTableFields=True
SupportsNonImageFiles=True
SetupProgram=Minimal CM Setup
[Setup Programs]
Minimal CM Setup
[Minimal CM Setup]
Visible=0
OCXFile=Quipu/CM/Quipu.KC.CM/Quipu.KC.CM.exe
ProgID=Quipu.KC.CM.Setup
最后但同样重要的是,确保您的程序集是 COM 可见的:
我把整个代码都放在 GitHub 上了,请随意分叉。希望对你有帮助。