7

POSアプリケーション用のプリンタードライバーラッパーのようなものを作成しようとしています。これにより、印刷されたレシートをキャプチャして、元のプリンターに再度転送できます。

これまでのところ、「POS for .Net」の上にサービスオブジェクトとして実装しましたが、すべてがうまく機能しましたが、一部のレガシーPOSアプリケーションはOPOSのみをサポートしていることがわかりました。それらをサポートするには、「POS for .Net」サービスオブジェクトをOPOSサービスオブジェクトとして使用できるようにするか、CCOを使用して独自のOPOSサービスオブジェクトを作成する必要があります。

私の質問は次のとおりです。

  • これらのレガシーPOSアプリでは、POS for .Netソリューションを使用することも可能ですか?(はいの場合、どのように?)
  • OPOSサービスオブジェクトを構築する方法は?.Netフレームワーク(C#など)を使用できますか?
  • 私たちは正しいことをしていますか?領収書を取得するためのより良い方法はありますか(特にこれらのレガシーアプリの場合)?
4

2 に答える 2

6

Q)これらのレガシーPOSアプリでは、POS for .Netソリューションを使用することも可能ですか?(はいの場合、どのように?)

A)いいえ、これらのアプリはPOS for .Netライブラリを使用せず、POS for .Netレジストリキーを使用してサービスオブジェクトを検索しません。これらのアプリは、OPOS(OLE POS)レジストリエントリのみを使用して登録済みサービスを検索しますオブジェクトであり、通常はCCOを呼び出し、CCOはサービスオブジェクトを呼び出します。

Q)OPOSサービスオブジェクトを作成するにはどうすればよいですか?.Netフレームワーク(C#など)を使用できますか?

A)はい、.Netを使用して実行できますが、COMライブラリとして公開する必要があります。CCOにインターフェイスを実装するのが良い方法です。各デバイスにDLLがあり、必要なデバイスのDLLを参照します。 、そのインターフェイスを実装し、タイプをCOM表示としてマークし、GUIDとProgIdを追加し、regasmの「パス」/ register / codebase/tlbを使用して登録します。コマンドを実行し、必要なレジストリキーを追加します(UPOS仕様\開発ガイドドキュメントに記載されています)。これで完了です。少なくとも私が思ったとおりです。これにより、サービスにメソッドが不足していることを示すエラーが発生します。正しく実行するために必要なオブジェクト、これは難しい方法だと思いましたが、インターフェイスで参照されていない7つのメソッドがあります-UPOS仕様\開発ガイドドキュメントで参照されていますが-これらのメソッドは次のとおりです。

  1. COFreezeEvents:プロパティFreezeEventsと同じです。
  2. GetPropertyNumber:プロパティのインデックスによってnumeric \ Booleanプロパティの値を取得するために使用されます。これについては、後で詳しく説明します。
  3. SetPropertyNumber:プロパティのインデックスによってnumeric \ Booleanプロパティの値を設定するために使用されます。これについては、後で詳しく説明します。
  4. GetPropertyString:プロパティのインデックスによって文字列プロパティの値を取得するために使用されます。これについては後で詳しく説明します。
  5. SetPropertyString:プロパティのインデックスによって文字列プロパティの値を設定するために使用されます。これについては後で詳しく説明します。
  6. OpenService:メソッドopenと同じです。
  7. CloseService:メソッドcloseと同じです。

これらのメソッドを実装した後は、すべてが正常に機能します。これは、CCOインターフェイスで参照されていないため奇妙ですが、前述したように、これらはそれぞれUPOS仕様で参照されており、完全な説明があります。

OpenServiceメソッドとCloseServiceメソッドが存在する理由は、CCOライブラリがcomとして実装された場合、OpenメソッドとCloseメソッドの名前が適切でなく、OpenServiceとCloseServiceに変更する必要があったためです。同じことが、新しい名前のクレームとリリースにも当てはまります。 ClaimDeviceとReleaseDevice–ただし、これらはインターフェイスで正しく公開されています。残りのメソッドについては、理由を見つけることができませんでした。

Get\Setプロパティメソッド

これらの4つのメソッドは、オブジェクトのすべてのプロパティにアクセスするために使用されます。なぜですか?よくわかりませんが、Dispatchインターフェイスからオブジェクトにアクセスするためにこれらを使用する必要があるようですが、そのインターフェイスがデフォルトで使用できないのはなぜですか?C ++サービスオブジェクトは同じ方法で実装されていますか?答えがありません。

これらを正しい方法で実装するには、OPOSインストール(CCOインストール)の下のIncludeディレクトリを確認し、*。hiファイル(主にOpos.hiとOposPtr.hi(この場合はプリンター))を確認する必要があります。 、これらには、成功または失敗の列挙型などのCCOの定数が含まれ、これら4つのメソッドのプロパティインデックスとデバイスインデックスオフセットが含まれていることがわかります。

OPOS定数の数値を使用すると、PropIndexパラメータ値をオンにして、正しいプロパティ値を取得/設定するだけで済みます。

    if (PropertyIndexHelper.IsStringPidx(PropIndex))
    {
        switch (PropIndex)
        {
            case PropertyIndexHelper.PIDX_CheckHealthText:
                return _physicalPrinter.CheckHealthText;

            case PropertyIndexHelper.PIDX_DeviceDescription:
                return _physicalPrinter.DeviceDescription;

            case PropertyIndexHelper.PIDX_DeviceName:
                return _physicalPrinter.DeviceName;
                                  .
                                  .
                                  .
                                  .
                                  .
于 2013-05-16T09:52:49.020 に答える
3

MEYWDの答えをさらに進めるために、C#での基本的なインターフェイスの外観を投稿したいと思います。

[ComVisible(true), Guid("Put a GUID here")]
public interface IMSR
{
    //Common Opos
    [DispId(0x01)]
    int CheckHealth([In] int lLevel);
    [DispId(0x02)]
    int ClaimDevice([In] int lTimeOut);
    [DispId(0x03)]
    int ClearInput();
    [DispId(0x04)]
    int ClearInputProperties();
    [DispId(0x05)]
    int ClearOutput();
    [DispId(0x06)]
    int CloseService();
    [DispId(0x07)]
    int COFreezeEvents([In, MarshalAs(UnmanagedType.VariantBool)] bool Freeze);
    [DispId(0x08)]
    int CompareFirmwareVersion([In, MarshalAs(UnmanagedType.BStr)] string FirmwareFileName, [In, Out]ref int pResult);
    [DispId(0x09)]
    int DirectIO([In] int lCommand, [In, Out] ref int pData, [In, Out, MarshalAs(UnmanagedType.BStr)] ref string pString);
    [DispId(0x0A)]
    int OpenService([In, MarshalAs(UnmanagedType.BStr)] string lpclDevClass, [In, MarshalAs(UnmanagedType.BStr)] string lpclDevName, [In, MarshalAs(UnmanagedType.IDispatch)] object lpDispatch);
    [DispId(0x0B)]
    int ReleaseDevice();
    [DispId(0x0C)]
    int ResetStatistics([In, MarshalAs(UnmanagedType.BStr)] string StatisticsBuffer);
    [DispId(0x0D)]
    int RetrieveStatistics([In, Out, MarshalAs(UnmanagedType.BStr)] ref string pStatisticsBuffer);
    [DispId(0x0E)]
    int UpdateFirmware([In, MarshalAs(UnmanagedType.BStr)] string FirmwareFileName);
    [DispId(0x0F)]
    int UpdateStatistics([In, MarshalAs(UnmanagedType.BStr)] string StatisticsBuffer);
    [DispId(0x10)]
    int GetPropertyNumber([In] int lPropIndex);
    [DispId(0x11)]
    string GetPropertyString([In] int lPropIndex);
    [DispId(0x12)]
    void SetPropertyNumber([In] int lPropIndex, [In] int nNewValue);
    [DispId(0x13)]
    void SetPropertyString([In] int lPropIndex, [In, MarshalAs(UnmanagedType.BStr)] string StringData);
    //MSR Specific
    [DispId(0x14)]
    int AuthenticateDevice([In, MarshalAs(UnmanagedType.BStr)] string deviceResponse);
    [DispId(0x15)]
    int DeauthenticateDevice([In, MarshalAs(UnmanagedType.BStr)] string deviceResponse);
    [DispId(0x16)]
    int RetrieveCardProperty([In, MarshalAs(UnmanagedType.BStr)] string propertyName, [Out, MarshalAs(UnmanagedType.BStr)] out string cardProperty);
    [DispId(0x17)]
    int RetrieveDeviceAuthenticationData([In, Out, MarshalAs(UnmanagedType.BStr)] ref string challenge);
    [DispId(0x18)]
    int UpdateKey([In, MarshalAs(UnmanagedType.BStr)]string key,[In, MarshalAs(UnmanagedType.BStr)] string keyName);
    [DispId(0x19)]
    int WriteTracks([In] object data,[In] int timeout);
}

これはMSRの場合ですが、CommonOPOSメソッドはすべてのタイプのデバイスで同じです。したがって、変更する必要があるのは、DispID 0x14(20)以降だけです。私が行ったことは、OPOSドキュメントと比較して、彼らが付けた署名をC#に変換することでした。私はこの方法で約6つのSOを作成しましたが、さまざまなシナリオですべてが正常に機能しています。

もう1つの注意点は、OpenServiceメソッドにあります。最後の引数がオブジェクトであることがわかります。これがControlオブジェクトのインスタンスです。あなたがする必要があるのはあなたのためにCOMオブジェクトを公開するあなたのプロジェクトで別のインターフェースを作ることです。私のMSRの例に固執するために、ここにあなたが置くものがあります。

[ComImport, Guid("CCB91121-B81E-11D2-AB74-0040054C3719"), InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface COPOSMSR
{
    void SOData([In] int Status);
    void SODirectIO([In] int EventNumber, [In, Out] ref int pData, [In, Out, MarshalAs(UnmanagedType.BStr)] ref string pStrIng);
    void SOError([In] int ResultCode, [In] int ResultCodeExtended, [In] int ErrorLocus, [In, Out] ref int pErrorResponse);
    void SOOutputCompleteDummy([In] int OutputID);
    void SOStatusUpdate([In] int Data);
    void SOProcessID([Out] out int pProcessID);
}

私はOPOSのソースコードの署名です。ソースコードを検索すると、次のような小さなコメントが表示されます。(msr OPOSソースコードから)これは、イベントを発生させるために何を実装するかを知っているためです。

c:\ Program Files(x86)\ Opos \ oposSrc \ zMSR \ MSR.idl

[
    object,
    uuid(CCB91121-B81E-11D2-AB74-0040054C3719),
    dual,
    helpstring("IOPOSMSR 1.5 Interface"),
    pointer_default(unique)
]
interface IOPOSMSR_1_5 : IDispatch
{
// Methods for use only by the Service Object
    [id(1), hidden, helpstring("method SOData")] HRESULT SOData( [in] long Status );
    [id(2), hidden, helpstring("method SODirectIO")] HRESULT SODirectIO( [in] long EventNumber, [in, out] long* pData, [in, out] BSTR* pString );
    [id(3), hidden, helpstring("method SOError")] HRESULT SOError( [in] long ResultCode, [in] long ResultCodeExtended, [in] long ErrorLocus, [in, out] long* pErrorResponse );
    [id(4), hidden, helpstring("method SOOutputCompleteDummy")] HRESULT SOOutputCompleteDummy( [in] long OutputID );
    [id(5), hidden, helpstring("method SOStatusUpdate")] HRESULT SOStatusUpdate( [in] long Data );
    [id(9), hidden, helpstring("method SOProcessID")] HRESULT SOProcessID( [out, retval] long* pProcessID );

これらの2つの基本的なものを使用すると、SOを作成できます。イベントを発生させるのも非常に簡単です。これが私がテストとしてそれをした方法です

    public int OpenService(string lpclDevClass, string lpclDevName, object lpDispatch)
    {
        controlObject = (COPOSMSR)lpDispatch;
        controlObject.SOData(1)//I just fired a Data Event
    }

C ++でSOを構築するのは、C#よりも難しいというのも私の経験です。C#が非常に単純にするステップは他にもたくさんあります。

私が始めるのに十分な情報であったいくつかの良い読み物。

COM相互運用パート1:C#クライアントチュートリアル

http://msdn.microsoft.com/en-us/library/aa645736(v=vs.71).aspx

COM相互運用パート2:C#サーバーチュートリアル

http://msdn.microsoft.com/en-us/library/aa645738(v=vs.71).aspx

COMデータ型

https://msdn.microsoft.com/en-us/library/sak564ww%28v=vs.100%29.aspx

于 2014-02-13T16:29:19.707 に答える