top / index / prev / next / target / source

2004-01-07 diary: javax.print初体験

いがぴょんの日記 日記形式でつづる いがぴょんコラム ウェブページです。

old-v2

javax.print初体験

仕事で javax.printでサンプルPGを書きました。 , 次は SWT DLLでのWin32APIコールへと移っていく模様。 , 後日 大村忠史さんにスゴイ技を教えて頂く。

javax.print初体験

クライアントPC上のプリンタ列挙がJavaでできるか、っていうことで J2SE SDK 1.4.2 + Windowsで javax.printを初体験しました。(java.awt.printだけでなく javax側に新規追加されていたなんて ほとんど今までさわった事がありませんでした) javax.print.PrintServiceが切り口になります。ちょちょっとトイ・プログラムを書いたのですが、ユーザが登録したプリンタ名やカラー・白黒などはAPI経由で取得できるのですが、プリンタドライバ名や (もしあれば)IPアドレスは javax.printでは取得できませんでした。、、、もし 私の勘違いだったら ツッコミを入れてください。明日には swt_XXXX.dllでJNIな世界へと突入しようとしているものですから…。

2004/01/20 大村忠史さんからツッコミSubject: Javaから Windows のプリンタプロパティを呼び出す伊賀敏樹様。大村忠史です。ご無沙汰しております。伊賀さんの日記 2004/01/07 日記: javax.print初体験 を見てから気になっていました。 Java から Windows のプリンタプロパティを呼び出す方法がわかりました。(もう既にご存じなら、お騒がせしてすみません) 昨日調べてみて、この方法でうまく行く事を確認しました。以下のコマンドラインを実行すれば、プリンタプロパティを呼び出せます。 RUNDLL32 PRINTUI.DLL,PrintUIEntry /e /n "プリンタ名"

この プリンタ名 は、PrintServiceクラスの getName() で、取得したものが使えます。使用方法は こんな感じです。( 最初に取得した PrintService のプリンタのプロパティを呼び出す)

PrintService[] ps = PrintServiceLookup.lookupPrintServices(
DocFlavor.SERVICE_FORMATTED.PRINTABLE, null );

String printerName = ps[0].getName();
String cmd = "RUNDLL32 PRINTUI.DLL,PrintUIEntry /e /n \""+ printerName + "\"";
try{
  Runtime.getRuntime().exec( cmd );
}
  catch( Exception exc ){
  exc.printStackTrace();
}

また、Swingコンポーネントで作った自作のダイアログで、コンボボックスに列挙されたプリンタ一覧から、プリンタ名を選んで、そのプリンタのプロパティウインドウを呼び出す事も 可能です。ここで 問題になっているのは、プリンタドライバ名やIPアドレス付きでプリンタを取得する事でしたね。以下のコマンドラインを実行すれば、プリンタの設定情報ウインドウを呼び出せます。 RUNDLL32 PRINTUI.DLL,PrintUIEntry /Xg /n "プリンタ名"この プリンタ名 は、PrintServiceクラスの getName() で、取得したものが使えます。このような情報が 表示されます。 PrinterName: HP PSC 750 ShareName: プリンタ PortName: DOT4_001 <-- ネットワークプリンタの場合には、ここにIPアドレスが表示される。 DriverName: HP PSC 750 Comment: Location: SepFile: PrintProcessor: WinPrint Datatype: RAW Parameters: Attributes: <Shared|Local|DoCompleteFirst|> Priority: 1 DefaultPriority: 0 StartTime: 0 UntilTime: 0 Status: <>

Subject: Javaから Windows のプリンタプ設定情報をファイルに出力する大村忠史です。プリンタ情報が ウインドウに表示されるだけでは 物足りませんね。設定情報をプログラム内に取り込むには、いったんファイルに書き出して読み込めばOKですね。以下のコマンドラインを実行すれば、プリンタの設定情報をファイルに出力出来ます。 RUNDLL32 PRINTUI.DLL,PrintUIEntry /Xg /n "プリンタ名"* */f 出力ファイル名

この プリンタ名 は、PrintServiceクラスの getName() で、取得したものが使えます。ファイルは、プリンタ毎に別々の物を用意します。出力形式は、テキストですが、ユニコードになっています。(1文字2バイト)

以下のコードによって、接続されているプリンタの 設定情報を ファイルに出力出来ます。 PrinterProperty.java

import javax.print.*;

public class PrinterProperty {
  public static void main( String[] args ){
    PrintService[] ps =
    PrintServiceLookup.lookupPrintServices(
    DocFlavor.SERVICE_FORMATTED.PRINTABLE, null );
    for( int i=0 ; i< ps.length ; i++ ){
      String printerName = ps[i].getName();
      String fileName = "file"+ i + ".dat";
      System.out.println( printerName );
      String cmd1 = "RUNDLL32 PRINTUI.DLL,PrintUIEntry /Xg /n \""+ printerName + "\" /f " + fileName;
      try{
        Runtime.getRuntime().exec( cmd1 );
      } catch( Exception exc ) {
        exc.printStackTrace();
      }
    }
  }
}

ここからいがぴょん詳細なレポート、どうもありがとうございます。RUNDLL32を利用するとは 私にとっては盲点でした。びっくりしました。この方法だと JNIをコールせずに、しかもIPアドレスなどの詳細情報を かなりWindowsに近いところから取得する事ができますね。びっくりしました。

それにしても 大村忠史様を直接召還してしまうとは…、かなりびっくりしました。恐縮です。どうもありがとうございました。

SWTのDLLで Win32プログラミング

それでもって、プリンタドライバ名やIPアドレス付きでプリンタを列挙するには swt_XXXX.dll に手を出すしかないかなぁ、なんて思い始めています。明日 作業する予定です。話しは飛びますが、swt_XXXX.dllって すごいもので Cのソースファイルを作成せず、またC言語コンパイラを全く利用せずに、Win32APIをJavaから構造体を新規に作成したりして呼び出す事ができるんです。私は swt_XXXX.dll のその利用方法の経験はあるものの、仕事での採用は初体験です。とにかく C言語をいっさい利用せずに JavaからDLL呼び出しを行いたいのです。そしてそのニーズを swt_XXXX.dll は満たしてくれるのです。で、びっくりしたのは アルファシステムズの菅村さんが この swt_XXXX.dll を用いれば C言語をいじらずに JNIコールできちゃう優れものAPIだってことを 事前に知っていた点です。菅村さん、恐るべし。さすが 『ある開発者の日記』時代からの 『いがぴょんの日記』読者なだけのことはあります。C言語の経験があった上で Javaが使いこなせる人は やっぱりスゴイなぁ…。(一応私は 今のところ 自称C言語が使えない人ということで 通していたり…ということにしています)

、、、もし わかりやすい swt_XXXX.dll を用いたJNIプログラミングの紹介ページなんかがあったら、どなたかツッコミ下さい。まあ SWTのソースコードを見れば 一発で思い出すはずなのですけれどもね。

2004.01.08 後日談。SWTのDLLを利用して可能なのは 既に定義されている Win32 APIの呼び出しだけでした。定義されていない Win32 APIの呼び出しには やはりJNIを新規に作成する事が必要でした。あれれ、誤解していました。ただし 構造体に相当するものは JNIを利用せずに Javaだけで実装可能です。まあその点だけでも かなり画期的だと思います。はて 記憶が間違っていました。ちょっとショック。

一方 ちょっと前に SWTでいろいろできるなぁ と思っていたのは SWTのAPIを利用したOLE呼び出しです。これは代替案として すぐに Jakarta POIが思い浮かびます。なににせよ OLEやOCX関連ならすぐに SWTやJakarta POIというところにつながるのですが、この件とごちゃまぜになっていたような気もします。とりあえずこれを実現するためには Cコンパイラが必要になる模様。

2004.01.20 後日談 そして結局 プリンタのIPアドレス列挙は C言語で実装することになりました。ごく普通にC言語でAPIを呼び出して、それをJNIでコールというオーソドックスなパターンです。しかも実装そのものは 値段さえ折り合えば SVF開発元が行う事に…。(実働コードは既に手元にあるのですが、サポートの関係上、なるべくパッケージソフトベンダー側に作らせたいのであった)みなさま、お騒がせしました。

JAVA WORLDへの執筆依頼は 諸般の事情により断りました。しょぼん

JAVA WORLDへの執筆依頼が来ていたのですが、諸般の事情により断りました。仕事が忙しい上にまだ ZDNETの呪いの記事が片が付いていないので、仕方なく断りました。しょぼん。ちょっと悲しい。というか はやく あの ZDNETの呪いの記事をなんとかせねば…。どこかの土日がねらい目か…。でも土日は土日で 仕事を入れたり そこはそこで むちゃをしているからなぁ。

なんだか風邪っぽいです

東京の寮の部屋が乾燥しているからでしょうか、なんだかノドの中心に風邪っぽいです。ここは一つ養生しておくべきなのでしょうね。

田町の職場にて SEさん増殖

今行っている田町の職場でSEさんが更に増殖しました。私が始めて行った頃は、まだ 結構空席があったと思ったのに…。打ち合わせようのエリアにも どんどん座席が進出。ビルの窓から JRの車庫が見える お好みの場所があるんですが、そこにもだんだん人が埋まってくる模様です。とりあえず トイレの待ち行列計数が上昇しているように思えます。とくに『大』! 机やいすは増えても 『大』は増えないですねぇ…

いがぴょんの仕事

ここ1ヶ月 方式設計で ばりばり仕事をしています。ふりかえって私の仕事を見つめてみたら、サッカーでたとえるなら リベロ とかいうポジションです。でもボランチでは無いように思います。リベロとはいえセンターバック的な事は決してやっていません! 希望はファンタジスタとゆ~ポジションかなぁ、、、と、勝手に妄想してみました。少なくとも去年クラスチェインジしたはずの技術営業 という仕事とは 全く縁遠くなってきています。『自称技術営業』みたいな… (笑)

世間のニュースから () 2004


この日記について