为 pdf 操作创建自定义模块

create custom module for pdf manipulation

我想创建自定义 Kofax 模块。当涉及到批处理时,扫描的文档会转换为 PDF 文件。我想获取这些 PDF 文件,对其进行操作(向 PDF 文档添加自定义页脚)并将它们交还给 Kofax。

到目前为止我所知道的:

我有 APIRef.chm (Kofax.Capture.SDK.CustomModule) 和 CMSplit 作为示例项目。不幸的是我很难进入它。是否有任何资源逐步展示如何进入自定义模块开发?

所以我知道IBatch接口代表一个选择的批次,IBatchCollection代表所有批次的集合。

我只想知道如何设置 "Hello World" 示例并可以将我的代码添加到其中,我认为我什至不需要 WinForms 应用程序,因为我只需要操作 PDF 文件和就是这样...

Kofax 将批处理公开为 XML,而 DBLite 基本上是所述 XML 的包装器。该结构在 AcBatch.htm 和 AcDocs.htm 中进行了解释(可在 CaptureSV 目录下找到)。这是基本思想(仅显示文档):

  • AscentCaptureRuntime
    • 批量
      • 文件
        • 文档

单个文档本身具有子元素(例如页面)和多个属性(例如 ConfidenceFormTypeNamePDFGenerationFileName。这就是你想要的。以下是向下导航文档集合的方法,将文件名存储在名为 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 ControlWindows 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 上了,请随意分叉。希望对你有帮助。