sh1’s diary

プログラミング、読んだ本、資格試験、ゲームとか私を記録するところ

C# OS にインストールされているプリンターのアイコンを取得する

コントロールパネルの「デバイスとプリンター」には、各プリンターにアイコンイメージがあります。この記事は、このイメージを取得して表示するサンプルです。

コントロールパネル プリンターアイコンの例

実際に取得してみた例がこれです。

リストボックスにして表示しています

わりと思ったとおりにできたと思います。

ポイント

プリンターは Windows システムに存在する特殊なフォルダーの扱いになるため、メモ帳のファイルパスを取得して、ファイルパスからアイコンを取得するような手法をとることができません。

そのため、特殊フォルダーの存在するアドレス(ポインター)を取得して、処理をすすめる必要があるため、P/InvokeMarshal、参照渡しといったアンマネージド コードの扱いを避けることができません。

サンプルの表示部分

単純にリストに、プリンター名とアイコンを表示するだけの xaml を作成します。

<Window x:Class="PrinterIconSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PrinterIconSample"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <ListBox ItemsSource="{Binding InstalledPrinters}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Label VerticalAlignment="Center" VerticalContentAlignment="Center" 
                               Content="{Binding Item1}" />
                        <Image VerticalAlignment="Center" Source="{Binding Item2}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

これはサンプルをどう表示するか、というだけのコード。

使いかたは、一応こんな感じ。

InstalledPrinters = PrinterInfo.GetInstalledPrinters();

そのまま。

アイコンを取得するコード

PrinterInfo.GetInstalledPrinters() メソッドを呼び出すと、Tuple<string, BitmapSource> のペア値のコレクションが返却されます。

コレクションは、OS にインストールされているプリンター数返却されて、ペア値はそれぞれ(プリンター名、プリンターアイコン)です。

P/InvokeC# でどう使うのかというコードだと思う。

アンマネージドソースなので

モリーリークも一応チェック。1回取得した場合と、100回連続取得した場合でメモリーの使用量をチェックしてみました。大きな差はなさそうです。

1回でこれくらい増えた

サンプル

テストプログラムは GitHub の「Samples」に公開しています。今回のプログラムは「PrinterIconSample」です。

参考