WDM プリンタINFファイル解析一般
概要
WDM プリンタインストールの解析記事です。最近はPrinterってPDFに出力するだけだったりすることも多いですが、そういったプリンタのインストールってどんな感じの動きをするのかを知るのがこの記事になります。管理人程度の知識ではさほど解析できないと思いますが、まずはやってみましょう。
管理人はNuance社製Paperportというアプリケーションを持っているので、それがどういう仕組みになっているのかを確認してみます。Paperportは亡くなった技術ですので、Paperportを入手して、一緒に確かめることは難しいと思います。
PaparPortは印刷してPDF化する仕組みをもったアプリで主にjpg画像をpdfに変換する機能やOCR機能で読み取れた文字を画像の文字列部分に文字情報をOverlapすることができるツールです。ほかにもIMGやPDFの簡単な編集といった機能をもっていてPDFの積み重ね機能も含めて文書管理としての機能を体現しています。
印刷機能
Nuance PaperPortで、印刷機能のインストールがどんな感じになっているかを確認してみようと思います。
PaperPort Image Printerという名前で、他の機能とは完全に分離されていますが、ディレクトリには以下のようなファイル群がある。
<syntaxhighlight2 lang="txt">
ImagprnMigrate.exe
ImgPrnSetupLib.dll
Nuan.gpd
NuanImageConvert.exe
nuanoemuires.dll
NuanPrint.inf
NuanPrn.ini
nuanui.dll
NuanUNI.dll
</syntaxhighlight2>
この中のNuanPrint.infがインストールするときに実行するインストールファイルとなる。このファイルを右クリックして表示される[インストール]を選択する方法も多いですが、コマンドラインからインストールを起動する方法もあります。Windows10の管理人PCではどうやって起動するのがよいのかはわかっていません。まずはコマンドラインについてみてみましょう。
<syntaxhighlight2 lang="txt">
rundll32 printui.dll,PrintUIEntry /if /b "プリンタ名" /f NuanPrint.inf /r "lpt1:" /m "プリンタデバイス名"
</syntaxhighlight2>
上記のような感じのコマンドでインストールする方法があるらしい。上記のコマンドは、なかなかお目にかかるものではないです。なんじゃこれ!って感じ。ヘルプを出してみましょう。
<syntaxhighlight2 lang="txt">
rundll32 printui.dll,PrintUIEntry /?
</syntaxhighlight2>
と、こんな感じにすると、違うウィンドウが起動して各種オプションに関する説明が得られます。
<syntaxhighlight2 lang="txt">
使用法: rundll32 printui.dll,PrintUIEntry [オプション] [@コマンドファイル]
/a[ファイル] バイナリ ファイル名 /b[名前] 基本プリンター名 /c[名前] UNC コンピューター名 (リモート コンピューターで実行される場合) /dl ローカル プリンターを削除します /dn ネットワーク プリンター接続を削除します /dd プリンター ドライバーを削除します /e 印刷設定を表示します /f[ファイル] inf ファイルまたは出力ファイル /F[ファイル] /f で指定された INF ファイルが依存する INF ファイルの場所です /ga コンピューターごとのプリンター接続を追加します (接続はログオン時にユーザーに伝達されます) /ge コンピューターごとのプリンター接続を列挙します /gd コンピューターごとのプリンター接続を削除します (接続はユーザー ログオン時に削除されます) /h[アーキテクチャ] ドライバー アーキテクチャが x86、x64 または Itanium のうちの 1 つです。 /ia inf ファイルを使ってプリンター ドライバーをインストールします /id プリンター ドライバーの追加ウィザード使ってプリンター ドライバーをインストールします /if inf ファイルを使ってプリンターをインストールします /ii inf ファイルとプリンターの追加ウィザード使ってプリンターをインストールします /il プリンターの追加ウィザード使ってプリンターをインストールします /im プリンターの追加ウィザードで、ネットワーク プリンターをスキップしてプリンターをインストールします /in ネットワーク プリンター接続を追加します /ip ネットワーク プリンターのインストール ウィザードを使用してプリンターをインストールします /j[プロバイダー] プロバイダー名を印刷します /k 指定されたプリンターでテスト ページを印刷します (プリンターのインストール時にはこのコマンドは使えません) /l[パス] プリンター ドライバー ソース パス /m[モデル] プリンター ドライバー モデル名 /n[名前] プリンター名 /o プリンター キューを表示します /p プリンターのプロパティを表示します /q QUIET モード、エラー メッセージを表示しません /r[ポート] ポート名 /s サーバー プロパティを表示します /Ss プリンターの設定をファイルに保存します /Sr ファイルからプリンターの設定を復元します コマンドの最後に追加されるプリンター設定オプション フラグの保存または復元: 2 PRINTER_INFO_2 7 PRINTER_INFO_7 c 色のプロファイル d プリンター データ s セキュリティ記述子 g グローバル デバイス モード m 最小限の設定 u ユーザー デバイス モード r 名前の競合を解決する f 名前を強制する p ポートを解決する i ドライバー名の競合 /u ドライバーが既にインストールされている場合は、それを使います /t[#] 開始するインデックス ページ (0 から始まります) /v[バージョン] ドライバーのバージョンは "Type 2 - カーネル モード" と "Type 3 - ユーザー モード" のどちらかです /w 指定されたドライバーが inf ファイルにない場合にユーザーに確認します /y 通常使うプリンターに設定します /Xg プリンター設定を取得します /Xs プリンター設定を設定します /z このプリンターを自動共有にしません /Y プリンター名を自動生成しません /K /h オプションで 2、3、4 の値をそれぞれ x86、x64、Itanium として認識するように変更し、/v オプションで 3 の値を "Type 3 - ユーザー モード" として認識するように変更します /Z このプリンターを共有にします。/if オプションと組み合わせる必要があります /? このヘルプを表示します @[ファイル] コマンド ライン引数ファイル /Mw[メッセージ] コマンドを実行する前に警告メッセージを表示します /Mq[メッセージ] コマンドを実行する前に確認メッセージを表示します /W[フラグ] ウィザード用のフラグとスイッチを指定します (APW および APDW) r ウィザードの最終ページでウィザードを再実行できるようにします /G[フラグ] グローバルのフラグとスイッチを指定します w セットアップ時にドライバー警告 UI を表示しません (Super Quiet モード) /R 既存のドライバーを選択したドライバーに強制的に置き換えます
例:
サーバー プロパティの実行:
rundll32 printui.dll,PrintUIEntry /s /t1 /c\\machine
プリンター プロパティの実行:
rundll32 printui.dll,PrintUIEntry /p /n\\machine\printer
ローカルでプリンターの追加ウィザードの実行:
rundll32 printui.dll,PrintUIEntry /il
\\machine でプリンターの追加ウィザードを実行:
rundll32 printui.dll,PrintUIEntry /im /c\\machine
キュー表示の実行:
rundll32 printui.dll,PrintUIEntry /o /n\\machine\printer
inf インストールの実行:
rundll32 printui.dll,PrintUIEntry /if /b "Test Printer" /f c:\infpath\infFile.inf /r "lpt1:" /m "Brother DCP-128C"
inf インストールの実行 (inf に依存)。例では、prnbr002.inf は ntprint.inf に依存します。
rundll32 printui.dll, PrintUIEntry /ia /m "Brother DCP-128C" /K /h x64 /v 3 /f "c:\infpath\prnbr002.inf" /F "c:\infpath\ntprint.inf"
inf を使ったプリンターの追加ウィザードの実行:
rundll32 printui.dll,PrintUIEntry /ii /f c:\infpath\infFile.inf
付属のプリンター ドライバーを使ったプリンターの追加:
rundll32 printui.dll,PrintUIEntry /if /b "Test Printer" /r "lpt1:" /m "Brother DCP-128C"
コンピューターごとのプリンター接続の追加 (接続はログオン時にユーザーに伝達されます):
rundll32 printui.dll,PrintUIEntry /ga /c\\machine /n\\machine\printer /j"LanMan Print Services"
コンピューターごとのプリンター接続の削除 (接続はユーザー ログオン時に削除されます):
rundll32 printui.dll,PrintUIEntry /gd /c\\machine /n\\machine\printer
コンピューターごとのプリンター接続の列挙:
rundll32 printui.dll,PrintUIEntry /ge /c\\machine
inf を使ったプリンター ドライバーの追加:
rundll32 printui.dll,PrintUIEntry /ia /c\\machine /m "Brother DCP-128C" /h "x86" /v "Type 3 - User Mode" /f c:\infpath\infFile.inf
inf を使ったプリンター ドライバーの追加:
rundll32 printui.dll,PrintUIEntry /ia /K /c\\machine /m "Brother DCP-128C" /h "x86" /v 3
付属のプリンター ドライバーの追加:
rundll32 printui.dll,PrintUIEntry /ia /c\\machine /m "Brother DCP-128C" /h "Intel" /v "Type 3 - Kernel Mode"
プリンター ドライバーの削除:
rundll32 printui.dll,PrintUIEntry /dd /c\\machine /m "Brother DCP-128C" /h "x86" /v "Type 3 - User Mode"
プリンター ドライバーの削除:
rundll32 printui.dll,PrintUIEntry /dd /K /c\\machine /m "Brother DCP-128C" /h "x86" /v 3
通常使うプリンターとして設定:
rundll32 printui.dll,PrintUIEntry /y /n "printer"
プリンター コメントの設定:
rundll32 printui.dll,PrintUIEntry /Xs /n "printer" comment "My Cool Printer"
プリンター設定の取得:
rundll32 printui.dll,PrintUIEntry /Xg /n "printer"
プリンター設定の結果をファイルに保存:
rundll32 printui.dll,PrintUIEntry /f "results.txt" /Xg /n "printer"
プリンター設定コマンドの設定の使用法:
rundll32 printui.dll,PrintUIEntry /Xs /n "printer" ?
すべてのプリンター設定をファイルに保存:
rundll32 printui.dll,PrintUIEntry /Ss /n "printer" /a "file.dat"
すべてのプリンター設定をファイルから復元:
rundll32 printui.dll,PrintUIEntry /Sr /n "printer" /a "file.dat"
レベル 2 のプリンター情報をファイルに保存 :
rundll32 printui.dll,PrintUIEntry /Ss /n "printer" /a "file.dat" 2
プリンター セキュリティ記述子をファイルから復元:
rundll32 printui.dll,PrintUIEntry /Sr /n "printer" /a "file.dat" s
プリンター グローバル デバイス モードとプリンター データをファイルから復元:
rundll32 printui.dll,PrintUIEntry /Sr /n "printer" /a "file.dat" g d
最小設定をファイルから保存とポート名の解決:
rundll32 printui.dll,PrintUIEntry /Sr /n "printer" /a "file.dat" m p
プリンターのクライアント サイド レンダリングの有効化:
rundll32 printui.dll,PrintUIEntry /Xs /n "printer" ClientSideRender enabled
プリンターのクライアント サイド レンダリングの無効化:
rundll32 printui.dll,PrintUIEntry /Xs /n "printer" ClientSideRender disabled </syntaxhighlight2>
上記の内、通常のプリンタインストールでよく使うオプションは
- /if
- inf ファイルを使ってプリンターをインストール。
- /b [名前]
- 基本プリンター名。
- /f [ファイル]
- inf ファイルまたは出力ファイル
- /r [ポート]
- ポート名
- /m [モデル]
- プリンター ドライバー モデル名
infファイル
上記のようなプリンタインストールコマンドがありますが、結局のところ、infファイルに記述される一連のインストール情報に従って、プリンタシステムが構築されているようです。
どういう風にプログラム群を配置するとpdfのようなプリンタ出力システムが構築されるのかを確認します。個々のプログラムファイルの作り方はもう少し難しいと思うので、まずは、どんなふうにファイルが配置されるのかをinfファイルの理解と共に知っていこうと思います。
まずはPaperPortインストールのテキストファイルがどうなっているかを見てみます。
<syntaxhighlight2 lang="INI" line=1>
- @file NuanPrint.inf for 32 and 64Bit System
[Version] Signature="$Windows NT$" Provider=%AUTHOR% LayoutFile=ntprint.inf ClassGUID={4D36E979-E325-11CE-BFC1-08002BE10318} Class=Printer
- Date & version of driver package
DriverVer=05/12/2006,1.0.0.0
- Manufacturer section
[Manufacturer] "Scansoft" = Scansoft,NTamd64
- Model Sections
- These sections correspond with an entry listed in the
- [Manufacturer] section above. The models will be displayed in the order
- that they appear here.
[Scansoft] "PaperPort Image Printer" = Nuan.gpd
[Scansoft.NTamd64] "PaperPort Image Printer" = Nuan.gpd
- Installer Sections
- These sections control file installation, and reference all files that
- need to be copied. The section name will be assumed to be the driver data
- file, unless there is an explicit DataFile section listed.
[Nuan.gpd] CopyFiles=@Nuan.gpd,@NuanPrn.ini,DLLFILES DataSection=UNIDRV_DATA DataFile=Nuan.gpd Include=NTPRINT.INF Needs=UNIDRV.OEM,UNIDRV_DATA
- Copy Sections
[DLLFILES] NuanUNI.DLL NuanUI.DLL Nuanoemuires.dll NuanImageConvert.exe
- Data Sections
- These sections contain data that is shared between devices.
- Call SetupSetDirectoryId with 66000 to set the target directory at runtime
- (depending on which environment drivers are getting installed)
[DestinationDirs] DefaultDestDir=66000
- diskid = description,tagfile,unused,subdir
[SourceDisksFiles.x86] Nuanuni.dll = 1,,,,,,,11,\i386 Nuanui.dll = 1,,,,,,,11,\i386 Nuanoemuires.dll= 1,,,,,,,11,\i386 NuanImageconvert.exe= 1,,,,,,,11,\i386 [SourceDisksFiles.amd64] Nuanuni.dll = 1,,,,,,,11,\amd64 Nuanui.dll = 1,,,,,,,11,\amd64 Nuanoemuires.dll= 1,,,,,,,11,\amd64 NuanImageconvert.exe= 1,,,,,,,11,\amd64
- Localizable Strings
[Strings] AUTHOR="Scansoft wintone"
</syntaxhighlight2>
INFファイルの読み解き
マイクロソフトの公式の解説は公式解説で記載されています。公式解説。正直エグイほど、ややこしいけど適格な情報。管理人のような素人には太刀打ちできない難しさがあります。プリンタインストールだけに限ればこれほど膨大な情報は必要ないのかもしれない。ここでは最低限の理解から始めてみます。
INFファイルはINIファイルともよくている構造になっています。両方に共通することもありそうです。まずはファイルの先頭あたりから理解していきます。
Version
- 4行目:[Version]
- [Version]のような記述がタイトルのようになって表記されます。これをセクションと呼んでいます。区分ですね。たしかに、[Version]のような記述ごとに分けられて記述があるように感じます。納得できる。
- その前に、行頭のセミコロン(;)とかは、コメントの記述に使われます。その行のセミコロンの後ろはコメントとして扱えるようです。行の途中からでもコメントが添えられますが、コメント化の打消しはできないので、;を入力したらINFコマンドの内容としては、その行はおしまいなのでしょう。
- イコール(=)はプログラムで使われるものと同じ意味を持っていて、イコールの右側(右辺値)の値をイコールの左側(左辺値)のキーワードに代入あるいは関連付けるという動きをします。
- INFファイルにおけるセクション名は変数のような意味を持つ場合があります。例えば、27行目の=の後ろNuan.gpdは39行目の[Nuan.gpd]の事を意味していて39行目の[Nuan.gpd]からのセクションの値をすべて27行目のNuan.gpdが指し示しています。27行目のNuan.gpdが"PaperPort Image Printer"という値だと指示しています。
- INFファイルにおけるセクションはINIファイルよりも意味がある。
- 5行目:Signature="\$WINDOWS NT\$"
- \$WINDOWS NT\$は何かのパスを指し示しいるわけではなく、署名はWINDOWS NTというすべてのシステムに対応する署名方式を使いますというお決まりの記述です。すべてのWindowsシステムで共通の値です。深く考える必要はないと思います。Signature="\$Chicago\$"でも同じ意味だそうですが、こちらの記述を使ったINFファイルを見かけたことはありません。
- 6行目:Provider=%AUTHOR%
- Providerはドライバの製造元を表す文字列を指定します。Providerキーワードの右辺値は文字列を指定します。ダブルクォーテーションで囲った文字列をProvider="Scansoft wintone"のように指定しても良いですし、このinfファイルのように%AUTHOR%と指定して、AUTHORという変数の中身を製造元に指定するというやり方でも良いです。%AUTHOR%と指定した場合は、後に出てくる85行目の[Strings]セクションで、変数の中身を指定する必要があります。86行目でAUTHOR="Scansoft wintone"という記述で文字列変数のようにAUTHORキーワードに文字列を紐づけることができます。
- 製造元情報はプリンタインストール後にもプリンタのプロパティとして参照できる値ですので、この仕組みを実現するためにあると思われます。マイクロソフトが製造元の場合はProvider=%msft%と指定され、[Strings]セクションでmsft="microsoft"と指定されるような構造になっているのを見かけます。
- 7行目:LayoutFile=ntprint.inf
- LayoutFileは共通するINFファイルの情報を読み込んだりするためにあります。windows2000、windowsXPで使われていたようで、現在では使わないことが推奨されています。INCLUDEというキーワードでntprint.infを取り込むのが主流のようです。Windows10でもpaperportのプリンタインストールはうまく出来ているので、使えなくもない指定方法なのかなと感じます。公式の解説文書はあまり深く言及していない、謎だわぁ。LayoutFileはDisplayドライバのインストールをするときには利用することにはなっているみたいです。なので、[Version]セクションではLayoutFileの指定をせず、INCLUDEキーワードでntprit.infの読み込みを指定するのが正しいやり方のように感じます。それが証拠に45行目でもINCLUDE=NTPRINT.INFと指定されています。
- ntprint.infって何?って感じですが、マイクロソフトユニバーサルプリンタドライバ (Unidrv) を意味していて、この共通の部品をインストールして、独自のドライバと併せて動かすことができます。
- 8行目:ClassGUID={4D36E979-E325-11CE-BFC1-08002BE10318}
- ClassGUIDはINFファイルの属性を示すIDでPrinterドライバは上記のようなIDになります。わけのわからない数字と英字の連続に見えますが、GUID(Globally Unique Identifier)生成器を使えば100年間ずっと毎秒10億個発番しつづけても重複しないといわれている唯一のIDになっています。世界の人口の10人に1人が毎秒1個発番する専属の担当と指名されたとしても、休みなく発番しつづけても重複しないということです。専属の人なんているわけないし、10人に1人が発番しているなんていうことも考えられません。そうすると上記番号は、この世界における単一目的のために発番した唯一のIDで、このIDがprinterドライバを表すIDになっているということです。これだけ長い英数字でありながらprinterドライバなら同じように4D36E979-E325-11CE-BFC1-08002BE10318が指定されます。
- 9行目:Class=printer
- このINFファイルの属性をあらわすキーワードでClass=printerならプリンタドライバであることを意味しています。
- 12行目:DriverVer=05/12/2006,1.0.0.0
- INFファイルによってインストールされるドライバの更新日付とバージョン番号に関する情報です。例では、5月12日で2006年の更新日でバージョン番号としては1.0.0.0が付与されています。ドライバインストーラー自体は更新されることが少ないので、1.0.0.0のまま終わることも多いと思います。
Manufacturer
17行目:"Scansoft" = Scansoft,NTamd64
- 先述のAUTHORのように%MANURACTURERNAM%のように変数を記述して[Strings]セクションでその実態を%MANURACTURERNAM%="製造元名"として表記することができます。変数を使わずに直接、二重引用符で製造元名を記述しても良いです。ここでは"Scansoft"=となっているので二重引用符で製造元名を指定しています。右辺値にはプリンタモデルについて記載されるセクションの値を記入する必要があります。CPUのモデルやOSのバージョンによってプリンタモデルのセクションの適用箇所を自動的に判別して、必要なプリンタモデルを選択できる仕組みがあるため、製造元名=の右辺値は複雑な決まりがいくつかあります。次の段落では右辺値のメカニズムについてを簡単にまとめたものを記述します。
製造元名=に続く値は一つ以上のセクション名が必要ですが、セクション名と同一のセクションが後述のINFファイル内に存在しなくても良いです。無い場合は、すべてのCPUアーキテクチャーについてのセクションが必要となります。
セクション名と同じものを含む場合
<syntaxhighlight2 lang="INI">
[Manufacturer]
"Scansoft" = Scansoft
[Scansoft] …… …… </syntaxhighlight2>
右辺値がセクション名と同じものを含まない場合
<syntaxhighlight2 lang="INI">
[Manufacturer]
"Scansoft" = Scansoft,NTx86,NTamd64,NTia64,NTarm,NTarm64
[Scansoft.NTx86] …… [Scansoft.NTamd64] …… [Scansoft.NTia64] …… [Scansoft.NTarm] …… [Scansoft.NTarm64] …… </syntaxhighlight2>
上記のように対応するアーキテクチャーすべてについてのセクションが無いとすべてのWindowsシステムへのドライバインストールを網羅はできません。共通のインストール処理で問題ない場合は、上記の例で[Scansoft]というセクションを配置して、セクションの中で必要なドライバインストール指示を記述します。
アーキテクチャは以下のように分類されます。
<ytmath>
<style>
table td {
background: #eee;
padding-left:10px;
} table tr:nth-child(odd) td { background: #fff; } </style>
アーキテクチャ略称 | 説明 |
x86 | intel x86 32bitアーキテクチャ(amd製も含まれる) |
amd64 | amd x64 64bitアーキテクチャ(32bit互換/Intel製も含まれる) |
ia64 | Intel Itanium64bitアーキテクチャ |
arm | arm 32bitアーキテクチャ |
arm64 | arm 64bitアーキテクチャ |
</ytmath>
amd64アーキテクチャーが今の流行りだと思います。CPUと聞くとIntelなイメージがありますが命令セット名はamd64という名前がついています。Intel Core i3/i5/i7 IntelAtomプロセッサもamd64です。サーバ側はiaなのでIntelという意味がねじ込んでありますが、i3/i5/i7 IntelAtomプロセッサがamd64命令セットであるのはIntelにとっては気持ちのいいものではないのかもしれません。やるなAMD(アドバンストマイクロデバイセズ)
アーキテクチャーの下でさらに細分化してセクションを分類できます。
<ymath>
Windows version | Major version |
Windows 10 | 10 |
Windows Server 2012 R2 | 6 |
Windows 8.1 | 6 |
Windows Server 2012 | 6 |
Windows 8 | 6 |
Windows Server 2008 R2 | 6 |
Windows 7 | 6 |
Windows Server 2008 | 6 |
Windows Vista | 6 |
Windows Server 2003 R2 | 5 |
Windows Server 2003 | 5 |
Windows XP | 5 |
Windows 2000 | 5 |
</ymath>
Windows Client <ymath>
Windows version | Major version |
Windows 10 | 10 |
Windows 8.1 | 6 |
Windows 8 | 6 |
Windows 7 | 6 |
Windows Vista | 6 |
Windows XP | 5 |
</ymath>
Windows Server <ymath>
Windows version | Major version |
Windows Server 2012 R2 | 6 |
Windows Server 2012 | 6 |
Windows Server 2008 R2 | 6 |
Windows Server 2008 | 6 |
Windows Server 2003 R2 | 5 |
Windows Server 2003 | 5 |
Windows 2000 | 5 |
</ymath>
Windowsのシステム名が変わるほどの変更で、あきらかに大きな変更なのに案外メジャーバージョンの番号って上がらない。実際は、マイナーバージョンまで記述して、やっとで思うような切り分けができそうな感じさえする。
Windows Client
<ymath>
Windows version | Major version | Minor version |
Windows 10 | 10 | 0 |
Windows 8.1 | 6 | 3 |
Windows 8 | 6 | 2 |
Windows 7 | 6 | 1 |
Windows Vista | 6 | 0 |
Windows XP | 5 | 1 |
</ymath>
Windows Server <ymath>
Windows version | Major version | Minor version |
Windows Server 2012 R2 | 6 | 3 |
Windows Server 2012 | 6 | 2 |
Windows Server 2008 R2 | 6 | 1 |
Windows Server 2008 | 6 | 0 |
Windows Server 2003 R2 | 5 | 2 |
Windows Server 2003 | 5 | 2 |
Windows 2000 | 5 | 0 |
</ymath>
例えばWindows10ビルド19042.867に対応するセクションを作りたい場合は
<syntaxhighlight2 lang="INI"> [Manufacturer] "ManufacturerID"=ManufacturerID,NTamd64.10.0...19042
[ManufacturerID.NTamd64.10.0...19042] …… </syntaxhighlight2>
のようにします。 右辺値に記述した値はモデル名として扱われます。まぁでも、INFファイルって意外に自動判定とかの機能が働くんすね。すごい。Windowsのバージョン番号とかアーキテクチャーをこんな簡単に判断するなんて、昔から高度な機能を実装してたんですね。
Model Sections
Manufacrurerの右辺値に設定したモデル名ごとのプリンタ設定を記述するセクションの指定をします。例では、2つのモデル名ScansoftとScansoft.NTamd64を指定しています。このセクションの中で設定する左辺値はプリンタドライバ名で右辺値はインストーラセクション名になります。モデル名で分岐したものが結局は同じインストーラセクション名になることがあります。今回の例でも、同じインストーラセクションになっています。
- 26行目:[Scansoft]
- 27行目:"PaperPort Image Printer" = Nuan.gpd
- [Scansoft]セクションはCPUのアーキテクチャーamd64以外で適用される、OSの種類に関係なくアクティブになるセクションです。プリンタドライバ名はPaperport Image Printerで、その中身であるインストーラセクションはNuan.gpdセクションを参照するように設定しています。
- 26行目:[Scansoft.NTamd64]
- 27行目:"PaperPort Image Printer" = Nuan.gpd
- [Scansoft.NTamd64]セクションも、[Scansoft]セクションと同じ設定になっています。
- 例えば、Intel Atom プロセッサのWindows10はamd64アーキテクチャなので、[Scansoft.NTamd64]のセクション内容が適用されます。そうするとIntel AtomプロセッサのWindows10はここまでの設定で
[Versions] <ymath>
Var | Value |
Signature | "\$Windows NT\$" |
Provider | "Scansoft" |
LayoutFile | ntprint.inf ; 無効な行 |
ClassGUID | {4D36E979-E325-11CE-BFC1-08002BE10318} |
Class | Printer |
DriverVer | 05/12/2006,1.0.0.0 |
</ymath>
[Manufacturer]
<ymath>
Var | Value |
"Scansoft" | Scansoft,NTamd64 ; [Scansoft.NTamd64] |
</ymath>
[Scansoft.NTamd64]
<ymath>
Var | Value |
"PaperPort Image Printer" | Nuan.gpd |
</ymath>
- のように設定されたことになります。
Installer Sections
Manufacrurerの右辺値に設定したモデル名ごとのプリンタ設定を記述するセクションの指定をします。例では、2つのモデル名ScansoftとScansoft.NTamd64を指定しています。このセクションの中で設定する左辺値はプリンタドライバ名で右辺値はインストーラセクション名になります。モデル名で分岐したものが結局は同じインストーラセクション名になることがあります。今回の例でも、同じインストーラセクションになっています。
- 39行目:[Nuan.gpd]
- Model Sectionsで指定した[Nuan.gpd]というセクションでInstallに必要な情報記述するインストーラセクションの情報を記述します。
- 40行目:CopyFiles=@Nuan.gpd,@NuanPrn.ini,DLLFILES
- インストーラセクション中の左辺値CopyFilesはインストールドライバ元で用意したファイルの内コピーするファイルを右辺値で指定します。@マークがついている名称はファイルの実体そのものの名称であることを示していて、変数とかではないことを意味しています。例でいうと、ドライバのINFファイルがあるディレクトリと同じ階層にNuan.gpdとNuanPrn.iniがあることを意味していて、これらをコピーすることを意味しています。@マークのついていないDLLFILESは[DLLFILES]というセクションで個別にコピーするファイルを指定することを意味しています。
- 41行目:DataSection=UNIDRV_DATA
- インストーラセクション中の左辺値DataSectionは各種プリンタで共通するインストールドライバを読み込むために指定します。マイクロソフトINFプリンタNtprint.infでは3つの有効なドライバセクションが存在しています。
Microsoft's DataSection <ymath>
DataSection | Value |
UNIDRV_DATA | ■共通プリンタードライバ ・Driverファイル ・Configファイル ・Help ファイル の値を割り当てる |
PSCRIPT_DATA | ■ポストスクリプトプリンタードライバ ・Driverファイル ・Configファイル ・Help ファイル の値を割り当てる |
UNIDRV_BIDI_DATA | ■双方向プリンターの場合 Microsoftユニバーサル プリンター ドライバー ・Driverファイル ・Configファイル ・Help ファイル ・言語モニターエントリ の値を割り当てる |
</ymath>
- 42行目:DataFile=Nuan.gpd
- インストーラセクション中の左辺値DataFileはドライバーに関連付けられたデータファイルの名前 (GPD、PPD ファイルなど)を指定します。GPD(Generic Printer Description)ファイルやPPD(PostScript Printer Description)ファイル自体も記述する項目に決まりのあるドライバデータとなっています。GPDファイル概要、OEMプリンタカスタムGPDサンプル、プリンタ設定GPDサンプルはこちらの手順で取得できます。PPDファイル開発はこちらが詳しいでしょうか。難しいですけど。
- 43行目:Include=NTPRINT.INF
- インストーラセクション中の左辺値Includeは追加のシステム提供のINFファイルを指定します。 このエントリを指定すると、通常はNeedsエントリも指定されます。NTPRINT.INFを指定することが多いでしょう。
- 44行目:Needs=UNIDRV.OEM,UNIDRV_DATA
- インストーラセクション中の左辺値Needsは、追加のシステム提供のINFファイルから取り込むセクションを指定します。例の場合、NTPRINT.INFから[UNIDRV.OEM]セクションと[UNIDRV_DATA]セクションを取り込むことを意味しています。
Copy Sections
InstallセクションのCopyFilesでファイル名そのものではなく、セクションを指定したときの個別のファイル名を記述するセクションです。
- 49行目:[DLLFILES]
- DLLFILESは任意でつけられた名前ですが、InstallSectionsのCopyFilesの中で@無しの名前としてファイルをセクションで指定することを意図したものです。このセクションには、セクション名以降でファイル名を1行1ファイルで羅列します。
[DestinationDirs]
ファイルのコピー先を指定する部分です。DefaultDestDir=66000は既定の配布先を指定するもので66000はプリンタドライバの配置をする既定のディレクトリ名を示します。番号が特定のディレクトリ名を保持していて、この番号によるディレクトリ名指定の管理はかなりの数が登録されています。66000はGetPrinterDriverDirectoryというAPIを実行して返却される値です。diridと呼ばれています。Windows10のamd64アーキテクチャーの場合はC:\Windows\System32\spool\drivers\x64が返ってきます。diridについてはリンク先に記述があります。
エクセルがあれば、以下のコードをVBAのエディタに張り付けてGetPrnterDriverDirectoryの内容を確かめることができます。
<syntaxhighlight2 lang="VB">
Declare PtrSafe Function BeepAPI Lib "kernel32.dll" Alias "Beep" (ByVal dwFreq As Long, ByVal dwDuration As Long) As Long
Declare PtrSafe Function GetPrinterDriverDirectory Lib "winspool.drv" Alias "GetPrinterDriverDirectoryA" _
(ByVal pName As String, _ ByVal pEnvironment As String, _ ByVal level As Long, _ ByVal pDriverDirectory As String, _ ByVal cbBuff As Long, _ pcbNeeded As Long) As Long
Sub GetDir()
Dim level As Long Dim cbBuff As Long Dim pcbNeeded As Long Dim pName As String Dim pEnvironment As String Dim pDriverDirectory As String level = 1 'must be 1 cbBuff = 0 'must be 0 initially pDriverDirectory = vbNullString 'must be null string initially pName = vbNullString pEnvironment = vbNullString If GetPrinterDriverDirectory(pName, _ pEnvironment, _ level, _ pDriverDirectory, _ cbBuff, _ pcbNeeded) = 0 Then '1回目の呼び出しでは返却で必要な文字数を返すために呼び出します。 '最初はディレクトリ値は得られません。
pDriverDirectory = Space$(pcbNeeded) cbBuff = Len(pDriverDirectory) If GetPrinterDriverDirectory(pName, _ pEnvironment, _ level, _ pDriverDirectory, _ cbBuff, _ pcbNeeded) = 1 Then '2回目の呼び出しでは返却で必要な文字数設定して呼び出しているので 'ディレクトリ値が得られます。 Debug.Print Left$(pDriverDirectory, pcbNeeded) '取得できた値がイミディエイトウィンドウに表示されます。 End If End If
End Sub
</syntaxhighlight2>
[SourceDisksFiles]
[SourceDisksFiles]は[SourceDisksFiles.amd64]のようにアーキテクチャー情報が付加されたものを対象にすることができます。この欄で先述したCopyFileセクションで記載したファイル一つ一つの詳細情報を記述する部分です。ファイルがどこにあるのかといた情報をつけ足します。たとえINFファイルと同じ位置にあったとしても、ディレクトリの位置がどこなのかを明示する必要があります。
- 78行目:DNuanuni.dll = [1]1(=diskid),[2](=subdir),[3](upgradecode),[4](newinstallcode),[5](spare),[6](spare),[7](newfilename),11(=diskid),\amd64(=subidir)
- これを紐解くのは難しい。なんで1の後ろにカンマ7つもあるん?コレって感じです。1と11を先述したdiridで1はINFファイルがあるInstalFileドライブを意味しています。11はC:¥Windows¥System32です。WindowsディレクトリはほとんどのPCで共通ですが、名前を変更することもできるので、11が同じ役割のフォルダという風に紐づけられています。diridはややこしいけど、プリンタドライバをインストールする技術としては必要不可欠な便利なシステムです。
- カンマ7つは別の意味をもっています。[1]diskid, [2]subdir, [3]upgradecode, [4]newinstallcode, [5]spare, [6]spare, [7]newfilename
NTPRINT.INI
ntprint.iniの中身は以下のようになっています。 <syntaxhighlight2 lang="INI" line=1>
- NTPRINT.INF - Microsoft Windows Core Printer Driver Package
[Version] Signature="$Windows NT$" Provider="Microsoft" ClassGUID={4D36E979-E325-11CE-BFC1-08002BE10318} Class=Printer CatalogFile=ntprint.cat DriverIsolation=2 DriverVer = 06/21/2006,10.0.18362.1198
[Manufacturer] "Microsoft"=Microsoft,NTx86,NTAMD64,NTIA64,NTARM,NTARM64
[Microsoft.NTx86] "{D20EA372-DD35-4950-9ED8-A6335AFE79F0}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F0}, {D20EA372-DD35-4950-9ED8-A6335AFE79F0} "{D20EA372-DD35-4950-9ED8-A6335AFE79F1}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F1}, {D20EA372-DD35-4950-9ED8-A6335AFE79F1} "{D20EA372-DD35-4950-9ED8-A6335AFE79F2}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F2}, {D20EA372-DD35-4950-9ED8-A6335AFE79F2} "{D20EA372-DD35-4950-9ED8-A6335AFE79F3}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F3}, {D20EA372-DD35-4950-9ED8-A6335AFE79F3} "{D20EA372-DD35-4950-9ED8-A6335AFE79F5}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F5}, {D20EA372-DD35-4950-9ED8-A6335AFE79F5}
[Microsoft.NTAMD64] "{D20EA372-DD35-4950-9ED8-A6335AFE79F0}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F0}, {D20EA372-DD35-4950-9ED8-A6335AFE79F0} "{D20EA372-DD35-4950-9ED8-A6335AFE79F1}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F1}, {D20EA372-DD35-4950-9ED8-A6335AFE79F1} "{D20EA372-DD35-4950-9ED8-A6335AFE79F2}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F2}, {D20EA372-DD35-4950-9ED8-A6335AFE79F2} "{D20EA372-DD35-4950-9ED8-A6335AFE79F3}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F3}, {D20EA372-DD35-4950-9ED8-A6335AFE79F3} "{D20EA372-DD35-4950-9ED8-A6335AFE79F5}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F5}, {D20EA372-DD35-4950-9ED8-A6335AFE79F5}
[Microsoft.NTIA64] "{D20EA372-DD35-4950-9ED8-A6335AFE79F0}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F0}, {D20EA372-DD35-4950-9ED8-A6335AFE79F0} "{D20EA372-DD35-4950-9ED8-A6335AFE79F1}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F1}, {D20EA372-DD35-4950-9ED8-A6335AFE79F1} "{D20EA372-DD35-4950-9ED8-A6335AFE79F2}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F2}, {D20EA372-DD35-4950-9ED8-A6335AFE79F2} "{D20EA372-DD35-4950-9ED8-A6335AFE79F3}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F3}, {D20EA372-DD35-4950-9ED8-A6335AFE79F3} "{D20EA372-DD35-4950-9ED8-A6335AFE79F5}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F5}, {D20EA372-DD35-4950-9ED8-A6335AFE79F5}
[Microsoft.NTARM] "{D20EA372-DD35-4950-9ED8-A6335AFE79F0}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F0}, {D20EA372-DD35-4950-9ED8-A6335AFE79F0} "{D20EA372-DD35-4950-9ED8-A6335AFE79F5}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F5}, {D20EA372-DD35-4950-9ED8-A6335AFE79F5} "{B552DDF8-2832-417f-B1D3-B99D8E62808A}" = {B552DDF8-2832-417f-B1D3-B99D8E62808A}, {B552DDF8-2832-417f-B1D3-B99D8E62808A}
[Microsoft.NTARM64] "{D20EA372-DD35-4950-9ED8-A6335AFE79F0}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F0}, {D20EA372-DD35-4950-9ED8-A6335AFE79F0} "{D20EA372-DD35-4950-9ED8-A6335AFE79F1}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F1}, {D20EA372-DD35-4950-9ED8-A6335AFE79F1} "{D20EA372-DD35-4950-9ED8-A6335AFE79F2}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F2}, {D20EA372-DD35-4950-9ED8-A6335AFE79F2} "{D20EA372-DD35-4950-9ED8-A6335AFE79F3}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F3}, {D20EA372-DD35-4950-9ED8-A6335AFE79F3} "{D20EA372-DD35-4950-9ED8-A6335AFE79F5}" = {D20EA372-DD35-4950-9ED8-A6335AFE79F5}, {D20EA372-DD35-4950-9ED8-A6335AFE79F5}
[{D20EA372-DD35-4950-9ED8-A6335AFE79F0}] CopyFiles=UNIDRV,PJLMON.DLL,@TTFSUB.GPD,@LOCALE.GPD,@MSXPSINC.GPD
[{D20EA372-DD35-4950-9ED8-A6335AFE79F1}] CopyFiles=PSCRIPT,@MSXPSINC.PPD,@PSCRPTFE.NTF
[{D20EA372-DD35-4950-9ED8-A6335AFE79F2}] CopyFiles=PCLXL,@PCL5ERES.DLL,@PCL5URES.DLL,@PCL4RES.DLL
[{D20EA372-DD35-4950-9ED8-A6335AFE79F3}]
[{D20EA372-DD35-4950-9ED8-A6335AFE79F5}] CopyFiles=XPSDRV
[{B552DDF8-2832-417f-B1D3-B99D8E62808A}] CopyFiles=PSCRIPT_PCLXL_V4
- Microsoft Driver Core installs
- These sections are used by Printer OEMs to install Microsoft provided print drivers
- For Core Printer Driver {D20EA372-DD35-4950-9ED8-A6335AFE79F0}
- UNIDRV without PJLMON support
[UNIDRV.OEM] CopyFiles=UNIDRV
- UNIDRV with PJLMON support
[UNIDRV_BIDI.OEM] CopyFiles=UNIDRV,PJLMON.DLL
[UNIDRV_DATA] DriverFile=UNIDRV.DLL ConfigFile=UNIDRVUI.DLL HelpFile=UNIDRV.HLP
- Data section that attaches PJLMON as the driver Lang Monitor
[UNIDRV_BIDI_DATA] DriverFile=UNIDRV.DLL ConfigFile=UNIDRVUI.DLL HelpFile=UNIDRV.HLP LanguageMonitor="PJL Language Monitor,PJLMON.DLL"
- Section to allow OEMs to reference the Global Font Substitution Table
[TTFSUB.OEM] CopyFiles=@TTFSUB.GPD
- Section to allow OEMs to set locale dependencies
[LOCALE.OEM] CopyFiles=@LOCALE.GPD
- Section to allow OEMs to include core GPD file(s) for XPSDrv driver
[XPSGPD.OEM] CopyFiles=@MSXPSINC.GPD
- Section to allow OEMs to install PJLMON.DLL
[PJLMON.OEM] CopyFiles=PJLMON.DLL
- For Core Printer Driver {D20EA372-DD35-4950-9ED8-A6335AFE79F1}
- PSCRIPT
[PSCRIPT.OEM] CopyFiles=PSCRIPT
[PSCRIPT_FE.OEM] CopyFiles=PSCRIPT,@PSCRPTFE.NTF
[PSCRIPT_DATA] DriverFile=PSCRIPT5.DLL ConfigFile=PS5UI.DLL HelpFile=PSCRIPT.HLP
- Section to allow OEMs to include core PPD file(s) for XPSDrv driver
[XPSPPD.OEM] CopyFiles=@MSXPSINC.PPD
- For Core Printer Driver {D20EA372-DD35-4950-9ED8-A6335AFE79F2}
- Section to allow OEMs to install PCL6 support files
[PCLXL.OEM] CopyFiles=PCLXL,@PCL5ERES.DLL
[PCL5ERES.OEM] CopyFiles=@PCL5ERES.DLL
[PCL5URES.OEM] CopyFiles=@PCL5URES.DLL
[PCL4RES.OEM] CopyFiles=@PCL4RES.DLL
- For Core Printer Driver {D20EA372-DD35-4950-9ED8-A6335AFE79F3}
- Section to allow OEMs to use sRGB color profile
[sRGBPROFILE.OEM] ColorProfiles="sRGB Color Space Profile.icm"
- For Core Printer Driver {D20EA372-DD35-4950-9ED8-A6335AFE79F5}
[XPSDRV.OEM] CopyFiles=XPSDRV
[PSCRIPT] PSCRIPT5.DLL PS5UI.DLL PSCRIPT.HLP PSCRIPT.NTF PS_SCHM.GDL
[PJLMON.DLL] PJLMON.DLL,,,0x00000020 ; Copy only if new binary
[UNIDRV] UNIDRV.DLL UNIRES.DLL UNIDRVUI.DLL STDNAMES.GPD STDDTYPE.GDL STDSCHEM.GDL STDSCHMX.GDL UNIDRV.HLP
[PCLXL] PCLXL.DLL PCLXL.GPD P6FONT.GPD PJL.GPD P6DISP.GPD
[XPSDRV] MXDWDRV.DLL
- For Core Printer Driver {B552DDF8-2832-417f-B1D3-B99D8E62808A}
[PSCRIPT_PCLXL_V4] PSCRIPT5.DLL MSXPSINC.PPD PSCRIPT.NTF PSCRPTFE.NTF PS_SCHM.GDL ttfsub.gpd unires.dll PCLXL.DLL PCLXL.GPD PCL5ERES.DLL PCL5URES.DLL PCL4RES.DLL P6FONT.GPD PJL.GPD P6DISP.GPD
- Call SetupSetDirectoryId with 66000 to set the target directory at runtime
- (depending on which environment drivers are getting installed)
[DestinationDirs] DefaultDestDir=66000 PJLMON.DLL=66002
[SourceDisksFiles] LOCALE.GPD = 1 MSXPSINC.PPD = 1 MSXPSINC.GPD = 1 MXDWDRV.DLL = 1 PCLXL.DLL = 1 PCLXL.GPD = 1 PCL5ERES.DLL = 1 PCL5URES.DLL = 1 PCL4RES.DLL = 1 P6FONT.GPD = 1 PJL.GPD = 1 PJLMON.DLL = 1 P6DISP.GPD = 1 PSCRIPT5.DLL = 1 PS5UI.DLL = 1 PSCRIPT.HLP = 1 PSCRIPT.NTF = 1 PSCRPTFE.NTF = 1 PS_SCHM.GDL = 1 STDNAMES.GPD = 1 STDDTYPE.GDL = 1 STDSCHEM.GDL = 1 STDSCHMX.GDL = 1 ttfsub.gpd = 1 unidrv.dll = 1 unidrv.hlp = 1 unidrvui.dll = 1 unires.dll = 1
[ControlFlags] AlwaysExcludeFromSelect=*
[PrinterPackageInstallation] PackageAware=TRUE
[Strings]
- Localizable
Disk1="Windows Installation Disc"
[SourceDisksNames.x86] 1 = %Disk1%,,,"I386"
[SourceDisksNames.amd64] 1 = %Disk1%,,,"Amd64"
[SourceDisksNames.ia64] 1 = %Disk1%,,,"Ia64"
[SourceDisksNames.arm] 1 = %Disk1%,,,"arm"
[SourceDisksNames.arm64] 1 = %Disk1%,,,"arm64"
</syntaxhighlight2>