このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
続いて、IPersistFile インタフェースだ。
C# や Java では、インタフェースを実装したクラスは、
インタフェース自身のメソッドを public として持つが、
COM では、メソッド実行は必ずインタフェース型経由となる。
理由は割愛するが、上記の制約があるため、
COM クラスに例えメソッドを定義しても直接呼び出せず、
インタフェースを全て明示してアクセスする必要がある。
さて、ShortcutClass を初期化するためには、
IPersistFile を経由してファイルを指定する必要がある。
IPersistFile は非常によく使うインタフェースなので、
.NET でも、UCOMIPersistFile と言う名前で定義されている。
ファイルを読み込むためには、Load メソッドを使う。
引数の pszFileName はファイル名、
dwMode には 0 を指定しておけばデフォルトとなる。
では、これらを使って試してみよう。
スタートメニューにある「Windows Update」を読んでみる。
ColumnProvider として登録すると大変なので、
コンソールアプリケーションとして実行し、
Main から起動してテストしてみよう。
今日も一気に書く。
========== Test.cs ==========
using System;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using LoaferShellEx.Interop;
namespace LoaferShellEx {
internal class Test {
[STAThread]
static public void Main() {
const string path =
"C:\\Documents and Settings\\All Users\\Start Menu\\Windows Update.lnk";
// Shortcut オブジェクトを作成
ShortcutClass obj = new ShortcutClass();
try {
// IPersistFile インタフェースを取得し
UCOMIPersistFile pf = (UCOMIPersistFile)obj;
// ショートカットファイルを読み込み
pf.Load(path, 0);
// IShellLinkW インタフェースを取得する
IShellLinkW link = (IShellLinkW)obj;
// バッファを用意
StringBuilder target =
new StringBuilder(Constants.MAX_PATH);
// ショートカット先を得る
link.GetPath(target, target.Capacity,
IntPtr.Zero, SLGP.UNCPRIORITY | SLGP.RAWPATH);
// デバッグ出力
Debug.WriteLine(target.ToString());
} finally {
// COM オブジェクトを解放する
Marshal.ReleaseComObject(obj);
}
}
}
}
========== end of Test.cs ==========
順に見ていこう。
ShortcutClass の作成は、new で行う。
この時点ではインスタンスは初期化されていないので、
初期化用に、IPersistFile にキャストし、
Load メソッドを呼び出してファイルから読み込む。
続いて IShellLinkW にキャストし、GetPath を呼ぶ。
GetPath は、メソッド側が値を書き込むので、
GetPath に渡す StringBuilder には
あらかじめサイズを確保しておく必要がある。
StringBuilder の Capacity が容量となるので、
int を受け取るコンストラクタを使って、
Constants.MAX_PATH(260 文字)分確保しておく。
GetPath の最初の引数はバッファ、
第 2 引数はバッファの容量だ。
第 3 引数は NULL を渡すため、IntPtr.Zero を指定。
第 4 引数はパスの取得方法だが、
SLGP.UNCPRIORITY はとりあえず指定しておく、
SLGP.RAWPATH は環境変数なども展開されない。
最後にある Marshal.ReleaseComObject(obj) は、
COM オブジェクトを解放することを明示する。
.NET はガベッジコレクションベースのメモリ管理なので、
ShortcutClass はスコープを抜けてもすぐに解放されない。
COM では、参照カウントでインスタンスを管理しており、
使わなくなった参照はすぐに解放するのがマナーだ。
そこで、ReleaseComObject を使って、
参照カウントを直ちに減算させることで、
低水準の COM オブジェクトへの参照をすぐに解放させる。
さて、実行すると、以下のように表示された。
%SystemRoot%\system32\wupdmgr.exe
ひとまずは成功だ。