読者です 読者をやめる 読者になる 読者になる

ブラザーのラベルプリンタまわりを操作する b-PAC SDK を使ってみた

b-PAC C#

ブラザーのラベルプリンタでは、b-PAC SDKを使ってC#などからプリンタまわりを操作できます。ラベルプリンタからバーコードを印刷する時に手を加えられるため重宝しています。
アプリケーション開発ツール b-PAC|開発者ツール|ブラザー

b-PAC SDKの使い方に関しては、上記のページにあるヘルプファイルドキュメントに記載されています。ただ、一部悩んだところもあったので、メモを残しておきます。

 
目次

 

環境

  • Windows10
  • .NET Framework 4.6.1
  • Brother QL720-NW
  • b-PAC SDK 3.0.17
    • 3.1系もリリースされていますが、ドキュメントからだとAPIの互換性や機能における大きな差は無さそう
      • この点については、以下に追記しました
  • 印刷するラベルファイル(*.lbxファイル)に含まれるオブジェクトは以下の通り
オブジェクト名 種類 値の設定方法
Content テキスト doc.GetObject("Content").Textでテキストを設定
Barcode バーコード doc.SetBarcodeData(doc.GetBarcodeIndex("Barcode"), "<バーコードに変換する文字列>")でバーコードを設定*1

 
なお、以降のdocという表記は

var doc = new bpac.Document();

という変数を指すものとします。

 
2016/6/15追記ここから

上記で「b-PAC SDK 3.1系は機能における大きな差は無さそう」と書きましたが、以下の記事で書いたとおり、スクリプト系言語からPrintedEventイベントを拾えるようになっていました。結構大きな差ですので、何もなければ3.1系を使うのが良さそうです。
PrintedEventイベントについて | b-PAC SDKをPython + pywin32(win32com)で操作してみた - メモ的な思考的な

2016/6/15追記ここまで

 

プリンタまわりの情報の取得について

doc.Printer.GetInstalledPrinters()について

このメソッドで取得できるのは、Brotherのラベルプリンタのみでした。

他にインストールされている他社のインクジェットプリンタとかもありましたが、そちらは取得できませんでした。

 

メディア情報の取得について

doc.Printer.GetMediaId()などでプリンタにセットされているメディア(ラベルカートリッジ)情報を取得できます。

ただ、複数のプリンタがインストールされている場合には、そのうち一つのプリンタ分しか取得できませんでした。

そのため、doc.SetPrinter()で明示的にプリンタを設定することで、確実にメディア情報を取得できるようになりました。

doc.SetPrinter(printerName, false);
var mediaId = doc.Printer.GetMediaId();

 
なお、ラベルプリンタがオフライン、またはラベルがセットされていない場合には、

  • doc.Printer.GetMediaId()の戻り値は0
  • doc.Printer.GetMediaName()の戻り値は、""(長さゼロの文字列)

となります。

 

印刷完了時のイベントについて

b-PACでは、印刷完了時のイベントを受け取ることができます。

イベント発生時の処理は

void HandlePrinted(int status, object value)
{
    // イベント発生時の処理
}

という型のイベントハンドラとして作成します。

あとは、サンプルコードにある通り、bpac.IPrintEvents_PrintedEventHandler

doc.Printed += new bpac.IPrintEvents_PrintedEventHandler(HandlePrinted);

のように使ってPrintedイベントにイベントハンドラを追加すれば、印刷完了時のイベントが動作するようになります。

参考:イベント - C# によるプログラミング入門 | ++C++; // 未確認飛行 C

 

印刷時のカット設定について

ドキュメントにもありますが、doc.PrintOut()の第二引数にカット方法(bpac.PrintOptionConstants.bpoAutoCutなど)を指定しても、無効なままでした。

カット設定は

doc.StartPrint("", bpac.PrintOptionConstants.bpoCutAtEnd);

のように、StartPrint()メソッドで指定したものが利用されました。

なお、オプションを複数指定する場合は、

// 印刷設定開始:最後でカットし、品質優先印刷を行う
doc.StartPrint("", bpac.PrintOptionConstants.bpoCutAtEnd | PrintOptionConstants.bpoQuality);

のように、論理OR演算子 (|)を使います。
C# 演算子 - MSDN

 

トラブルシューティング

以下のページにいろいろとまとまっており、参考になりました。
たまにプログラマOYAJIの備忘録: b-PAC+PT-9700PC(PT-9800PCN)で、COM相互運用型エラー、エラーは出ないが印刷も出ない、COMエラー発生し印刷できない

 
ただ、この中で触れられているCOM相互運用型エラーについて、本当に相互運用機能型の埋め込みをFalseとするのが正解なのか、もう少し考えてみました。

上記のエラーが発生するのは、

var doc = new DocumentClass();

と実装した時です。この書き方は上記のページのソースコードの他、ヘルプドキュメントファイルのサンプルコードやC#のサンプルコードにもありました。

そのまま使用すると、

エラー CS1752 相互運用型 'DocumentClass' を埋め込むことができません。該当するインターフェイスを使用してください。

が.NET4.6.1環境でも発生します。

一方、同じヘルプドキュメントファイルの中にある、APIリファレンスでは

var doc = new bpac.Document();

という実装になっています。この書き方の場合、.NET4.6.1ではエラーは発生しません。

この差は、.NET 4にて相互運用機能の埋め込み(No-PIA)への対応だろうと考えました。.NET4以降はデフォルトで相互運用機能型の埋め込みTrueとなっているため、前者のNo-PIA非対応の書き方ではエラーになります。

念のため、提供されているサンプルのNamePlt.slnファイルを開くと、ファイルの先頭に

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005

という記載があり、提供されたサンプルはVisualStudio2005(.NET 2.0)で作成したもの(=No-PIA非対応)と考えられました。
.NET Framework のバージョンおよび依存関係 - MSDN

 
また、

などを参考にすると、No-PIAで書いたほうが良さそうでした。

そのため、

  • 相互運用機能型の埋め込みはTrue
  • var doc = new bpac.Document();

というNo-PIA対応の実装にしました。

 
なお、No-PIAで書くとInterop.bpac.dllなどがプロジェクトのbinフォルダに作成されませんが、頒布時にb-PACの使用許諾契約には引っかからないだろうと考えています。Interop.bpac.dllは.NETとCOMを橋渡しするために.NETが作り出したものであり、オリジナルは改変していないと考えているためです。

この部分で、もし認識に誤りがありましたら、ご指摘いただけるとありがたいです。

 

ソースコード

GitHubに上げてあります。
thinkAmi-sandbox/b-PACSample

 
なお、lbxファイルをアップロードして良いのか分からなかったため、今回は省略してあります。

 

その他参考

今回とは関係ありませんが、COMまわりを見ていた時に気になる記事があったので残しておきます。

*1:バーコードの種類は、lbxファイル側で設定