はじめに
パソコン本体を机の下に置いて使っていると、HDDにアクセスしているのかどうかがよく分かりません。特に、Windows Vistaはバックグラウンドでのディスクアクセスを頻繁に行っているため、モニタしか見ていない時はディスクアクセスをしているのかどうか、いちいちパソコン本体を覗き込まないと分かりません。
昔、Macintoshを使っているときに、デスクトップの右端にディスクアクセスのランプを点滅させるアクセサリがあったのを思い出し、Windowsでも使える同じようなプログラムを作ってみました。ディスクアクセスの状況は、PlusPak for Windows Forms 5.0JのGcProgressBarコントロールを使い、論理ドライブごとにアニメーション表示します。
対象読者
Visual Basic 2005・2008またはVisual C# 2005・2008を使ってプログラムを作ったことのある人。
必要な環境
Visual Basic 2005、2008またはVisual C# 2005、2008、Visual Studio 2005、2008でプログラムが作れる環境。
なお、本プログラムはWindows Vista上で動作するVisual Studio 2005を使用して作成し動作確認を行っています。
プログラム実行時の注意事項
PlusPak for Windows Forms 5.0Jを使って作成したアプリケーションを配布する場合、PlusPak for Windows Forms 5.0Jのアセンブリファイルを添付する必要があります。これは、Common Language RuntimeのDLLをアプリケーションと一緒に配布するのと同じです。
本記事のサンプルアプリケーションを正常に動作させるためには、次の4ファイルをインストールする必要があります。
ファイル名 | 説明 |
GrapeCity.Win.PlusPak.v50.dll | 本体コンポーネント |
GrapeCity.Framework.PlusPak.v20.dll | 製品のフレームワーク |
GrapeCity.Win.PlusPak.v50.resources.dll | 本体コンポーネントのサテライトリソース |
GrapeCity.Framework.PlusPak.v20.resources.dll | 製品フレームワークのサテライトリソース |
これらのファイルを、プログラムを実行するBinフォルダに格納します。.NET Framework 2.0から追加されたクラスやメンバを使用しているので、.NET Framework 2.0がインストールされていることが必須条件です。
なお、本サンプルのバイナリファイル(exeファイル)は、ドライブCのプログレスバーのみ動作します。複数のドライブで動作確認をする場合は、ソースファイルのドライブ名を変更して使用してください。
コントロールのインストール
はじめてPlusPak for Windows Forms 5.0Jを使用する方は、Visual Studio、Visual Basic、Visual C#の開発環境にPlusPak for Windows Forms 5.0Jをインストールする必要があります。インストーラは、グレープシティのWebページからダウンロードできます。
ユーザー情報を登録すると送られてくるメールにダウンロード用のURLが記載されているので、ここからダウンロードしてインストールしてください。ファイルはzip形式で圧縮されています。有償のコントロールですが、プロダクトキーを入力せずにインストールすることでトライアル版として使用できます。制限事項などの詳細についてはインストーラに同梱されているリリースノートを参照ください。
コントロールの追加
PlusPak for Windows Forms 5.0Jをインストールしたら、ツールボックスに専用のタブを作成し、使用するコントロールを追加します。追加するコントロールは、「.NET Frameworkコントロール」のアセンブリ名が「GrapeCity.Win.PlusPak」で始まるコントロール「GcProgressBar」です。
GUIのデザイン
今回使用するコントロールです。
1
フォームは、次のプロパティを設定し、デスクトップの左上にサイズ変更できない形に設定します。
プロパティ | 設定値 |
ControlBox | False |
FormBorderStyle | FixedToolWindow |
StartPosition | Manual |
Location | 0、0 |
2
Labelコントロールは、Imageプロパティにアイコンをセットしています。
3
Timerコントロールは、次のプロパティを設定します。
プロパティ | 設定値 |
Enabled | True |
Interval | 100 |
4
ContextMenuStripコントロールは「終了」メニューを作成し、ShortcutKeysプロパティに「Ctrl+X」を設定します。そして、フォームとフォーム上のすべてのコントロールの「ContextMenuStrip」プロパティに、このContextMenuStripコントロールを設定しておきます。
作成するプログラムの機能
このプログラムでは、Windowsのパフォーマンスカウンタの機能の一部を呼び出してPlusPak for Windows Forms 5.0JのGcProgressBarコントロールを使用し、Windows Vistaで使われているプログレスバーでディスクのアクセス状況を論理ドライブごとに表示します。
動作原理は簡単で、Windowsのパフォーマンスモニタにあるカウンタパラメータ「Disk Transfer」と同じものを.NET FrameworkのPerformanceCounterクラスを使って取得し、TimerコントロールのTickイベントハンドラで100ミリ秒ごとに更新していきます。パフォーマンスカウンタの取得方法さえ分かれば、ディスク容量の取得やCPUの稼動状況、メモリの空き容量など、パフォーマンスモニタで表示できるデータはほとんど取得できます。
今回は論理ドライブの転送(Read/Write)バイト量を取得し、GcProgressBarコントロールで表示します。ドライブの指定は自動で論理ドライブを設定する方法もありますが、記事ページの都合により最初から論理ドライブを指定する方法を使いました。
GcProgressBarコントロールの配置と設定
GcProgressBarコントロールはVS標準のProgressコントロールの機能拡張版で、Windows Vistaのアニメーション効果に加え、独自の進捗表示スタイルを作成できます。
塗りつぶしの方向やバー自体の向きの変更、設計時の書式設定によって現在の進行状況に関する詳細情報を文字としてコントロールに表示できます。
バーの動作範囲は「Maximum」と「Minimum」プロパティで設定でき、進行状況はValueプロパティに設定します。バーの数値表示は「DisplayTextFormat」プロパティで行います。あらかじめプリセットされている「値のタイプ」を使用し、これを元に加工することで自作の数値表示を行うことができます。
「値のタイプ」に使用できるキーワード
「値のタイプ」に指定できるキーワードは下記のとおりです。これらのキーワードのほかに、任意のリテラル文字と組み合わせて表示するテキストの書式を設定できます。
キーワード | 説明 |
[v] | コントロールの現在値(Value プロパティの値) |
[p] | 全体の進行範囲に対する完成の度合い(Value プロパティの値に基づいたパーセンテージ) |
[s] | 全体の進行範囲(Maximum - Minimum の値) |
[m] | コントロールの最小値(Minimum プロパティ) |
[M] | コントロールの最大値(Maximum プロパティ) |
[^v] | タスク完了までの残り値(Maximum - Value の値) |
[^p] | 全体の進行範囲に対する未完成の度合い(完了までの残り値に基づいたパーセンテージ) |
「値の書式」に使用できるキーワード
「値の書式」では、「値のタイプ」で設定する値の書式を指定します。書式に指定できるキーワードは下記のとおりです。それ以外の文字は使用できません。
キーワード | 説明 |
# | 数値の桁を指定します。値が0の場合は何も表示されません。 |
0 | 数値の桁を指定します。値が0の場合は0を表示します。 |
.(ピリオド) | 小数点の表示位置を指定します。 |
,(コンマ) | 桁区切り記号の表示位置を指定します。 |
今回は、取得するDisk Transfer値を正確に表示する機能ではなく、ディスクにアクセスしているかどうかを視覚的に表示するためだけなので、動作範囲は「Maximum」プロパティを1000に設定します。数値は表示しないのでDisplayTextFormatプロパティの値を削除します。
PerformanceCounterクラスの使い方
PerformanceCounterクラスは、先に説明したようにWindowsのパフォーマンスカウンタの機能を取り出して使うことができるクラスです。
この機能を使うには、「CategoryName」「CounterName」「InstanceName」「MachineName」の4つのプロパティを使用します。最低でも「CategoryName」「CounterName」を使用し、「InstanceName」「MachineName」はカウンタによって使用するかどうかが決まります。
使用するプロパティについては、コントロールパネルのアプリケーション「パフォーマンスモニタ」の「カウンタの追加」ダイアログで知ることができます。例えば、次の画面は「Processor」の「IdleTime」を表示するカウンタを追加しようとしています。リスト内の太字の文字が「CategoryName」、「%」で始まっているのが「CounterName」になります。そして、このカウンタではCoreDuoプロセッサのどちらのCPUの値を取り出すのかを選ぶリストが表示されますが、これが「InstanceName」になります。
「MachineName」はリストのコンピュータです。特にコンピュータを選ばなければ指定しません。
今回は、この中から「LogicalDisk」のカウンタ「Disk Transfers/sec」を使用します。「InstanceName」には各ドライブ名を指定し、それぞれのドライブでの転送速度を取得します。
Tickイベントの処理
実際にカウンタ値を取得する処理は、TimerコントロールのTickイベントハンドラで行います。既にTimerコントロールはIntervalプロパティを100ミリ秒に設定しているので、この時間間隔でプログレスバーの表示を更新するようにします。
オブジェクト変数の宣言
PerformanceCounterクラスはSystem.Diagnostics名前空間に属しているので、この名前空間をインポートします。
また、PerformanceCounterクラスのインスタンスへの参照を格納するオブジェクト変数を使用しますが、この変数宣言をモジュールレベルで行います。Tickイベントハンドラ内で宣言すると、毎回PerformanceCounterクラスのインスタンスを作成することになってしまい、プログラムは正常に動作しませんので注意してください。
なお、このプログラムでは、筆者のコンピュータに実装されている論理ドライブ「C」「E」「J」の3つのを対象にしています。サンプルプログラムの実行ファイルは、ドライブCのみ動作するように作成してありますが、違うドライブでも試したい場合は以降のコードのドライブ名を変更して使用してください。
Imports System.Diagnostics Public Class Form1 Private Disc1, Disc2, Disc3 As New PerformanceCounter()
using System.Diagnostics; namespace discind_cs { public partial class Form1 : Form { public Form1() { InitializeComponent(); } PerformanceCounter Disc1 = new PerformanceCounter(); PerformanceCounter Disc2 = new PerformanceCounter(); PerformanceCounter Disc3 = new PerformanceCounter();
最初の論理ドライブの情報取得
Tickイベントハンドラでは、取得したドライブ転送量を格納する変数を宣言します。これは、Visual BasicではSingleで、Visual C#ではfloat型で宣言します。というのも、パフォーマンスカウンタのデータを取得するNexVqalueメソッドの戻り値がこのデータ型だからです。
次に、PerformanceCounterクラスの3つのプロパティに、取得するカウンタのカテゴリ名、カウンタ名、インスタンス名を記述します。インスタンス名はドライブ名に「:」を付けた文字列になります。
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick Dim p1, p2, p3 As Single 'Disk1 Disc1.CategoryName = "LogicalDisk" Disc1.CounterName = "Disk Transfers/sec" Disc1.InstanceName = "C:"
private void timer1_Tick(object sender, EventArgs e) { float p1,p2,p3; //Disk1 Disc1.CategoryName = "LogicalDisk"; Disc1.CounterName = "Disk Transfers/sec"; Disc1.InstanceName = "C:";
そして、PerformanceCounterクラスのNextValueメソッドを実行します。このメソッドが、カウンタサンプル値を取得し返してきます。
後は、プログレスバーの範囲を超えないような処理を組み込み、GcProgressBarコントロールのValueプロパティに値を設定します。なお、GcProgressBarコントロールのMaximumプロパティ、ValueプロパティはいずれもDecimal型なので、データ型変換を行ってください。
p1 = Disc1.NextValue() If p1 > Me.GcProgressBar1.Maximum Then p1 = Me.GcProgressBar1.Maximum End If Me.GcProgressBar1.Value = CInt(p1)
p1 = Disc1.NextValue(); if (p1 > (float)gcProgressBar1.Maximum) { p1 = (float)gcProgressBar1.Maximum; } gcProgressBar1.Value = (decimal)p1;
残りのドライブの処理
同じように、残りのドライブの処理も作成します。違うのは、「InstanceName」プロパティの値とGcProgressBarコントロールのオブジェクト名だけです。
これでできあがりです。
'Disk2 Disc2.CategoryName = "LogicalDisk" Disc2.CounterName = "Disk Transfers/sec" Disc2.InstanceName = "E:" p2 = Disc2.NextValue() If p2 > Me.GcProgressBar2.Maximum Then p2 = Me.GcProgressBar2.Maximum End If Me.GcProgressBar2.Value = CInt(p2) 'Disk3 Disc3.CategoryName = "LogicalDisk" Disc3.CounterName = "Disk Transfers/sec" Disc3.InstanceName = "J:" p3 = Disc3.NextValue() If p3 > Me.GcProgressBar3.Maximum Then p3 = Me.GcProgressBar3.Maximum End If Me.GcProgressBar3.Value = CInt(p3)
//Disk2 Disc2.CategoryName = "LogicalDisk"; Disc2.CounterName = "Disk Transfers/sec"; Disc2.InstanceName = "E:"; p2 = Disc2.NextValue(); if (p2 > (float)gcProgressBar2.Maximum) { p2 = (float)gcProgressBar2.Maximum; } gcProgressBar2.Value = (decimal)p2; //Disk3 Disc3.CategoryName = "LogicalDisk"; Disc3.CounterName = "Disk Transfers/sec"; Disc3.InstanceName = "J:"; p3 = Disc3.NextValue(); if (p3 > (float)gcProgressBar3.Maximum) { p3 = (float)gcProgressBar3.Maximum; } gcProgressBar3.Value = (decimal)p3;
まとめ
GcProgressBarコントロールは、Windows XP/Vistaで使われているプログレスバーをアプリケーションに実装できるコントロールです。アニメーションの色やデザインを自作することができ、数値表示の書式も自由に行えます。今回はディスクアクセスのメーターに使用しましたが、このような視覚的に情報を伝える使い方も可能です。
PerformanceCounterクラスは、コンピュータのパフォーマンスに関するさまざまなデータをリアルタイムに取得できます。パフォーマンスカウンタの取得方法さえ分かれば、ディスク容量の取得やCPUの稼動状況、メモリの空き容量など、パフォーマンスモニタで表示できるデータはほとんど取得できます。
ガジェットにも、CPUメータやメモリメータを表示するものがいくつもありますが、多分仕組みは同じようにパフォーマンスカウンタで情報を取得し、グラフィックスなどで視覚化しているだけだと思います。使い方によっては、ユーザーの役に立つアプリケーションを作ることができるでしょう。