このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
インストーラやランチャーなどのプログラムでは、
ショートカットを作成する必要に迫られる場合がある。
今度は、ショートカットを作ってみよう。
まずはプロトタイプ宣言。
========== lnkfile.h (partial) ==========
HRESULT ShortcutCreate(const wchar_t *fileName, const wchar_t *target);
========== end of lnkfile.h (partial) ==========
ファイル名と、リンク先を指定して、
ショートカットを作成する。
次に、実装を追加する。
========== lnkfile.c (partial) ==========
HRESULT ShortcutCreate(const wchar_t *fileName,
const wchar_t *target) {
HRESULT result = S_OK;
IShellLink *link = NULL;
IPersistFile *pf = NULL;
result = CoInitialize(NULL);
if (FAILED(result)) return result;
result = CoCreateInstance(&CLSID_ShellLink, NULL,
CLSCTX_INPROC_SERVER, &IID_IShellLinkW, (void **)&link);
if (FAILED(result)) goto cleanup;
/* IShellLink#SetPath を利用してリンクを設定 */
result = IShellLinkW_SetPath(link, target);
if (FAILED(result)) goto cleanup;
/* IPersistFile のポインタも取得 */
result = IUnknown_QueryInterface(link,
&IID_IPersistFile, (void **)&pf);
if (FAILED(result)) goto cleanup;
/* IPersistFile#Save を利用して保存 */
result = IPersistFile_Save(pf, fileName, TRUE);
cleanup:
if (pf) IUnknown_Release(pf);
if (link) IUnknown_Release(link);
CoUninitialize();
return result;
}
========== end of lnkfile.c (partial) ==========
読み込みと比べても、基本的なところは変わらない。
IPersistFile#Load が IPersistFile#Save に、
IShellLinkW#GetPath が IShellLinkW#SetPath になる。
そう言えば、COM オブジェクトについて書いていなかった。
C 言語では、基本的に自分で生成したオブジェクトは、
自分で破棄しないといけないのだが、
COM オブジェクトには、少し特別な規則が存在する。
COM オブジェクトには、自動的な生存管理の仕組みがあり、
個々のオブジェクトは、自らの参照の数を管理している。
参照は、インタフェースポインタの数によって決まり、
全てのインタフェースポインタが解放されると、
COM オブジェクトのインスタンスは自動的に破棄される。
そのため、COM にはインスタンスを作成する関数はあるが、
インスタンスを破棄する関数は存在せず、
IUnknown#Release を呼び出すことで解放するのだ。
ショートカットの場合、2 つのインタフェースを使うが、
必要であればいつでも、QueryInterface を使って
任意のインタフェースポインタを取得することができる。
オブジェクトを指すインタフェースポインタが存在する限り、
インスタンスが破棄されることはないため、
インタフェースを取得するタイミングは特に制約はない。
さて、では実際に作成してみよう。
適当な wmain 関数を書いてみる。
========== program.c (partial) ==========
int wmain(int argc, wchar_t *argv[]) {
const wchar_t *path = L"C:\\メモ帳.lnk";
const wchar_t *target = L"C:\\WINDOWS\\system32\\notepad.exe";
HRESULT result = S_OK;
setlocale(LC_ALL, "Japanese");
result = ShortcutCreate(path, target);
if (result == S_OK) {
wprintf(L"ファイル名 : %s\n", path);
wprintf(L"ショートカット先: %s\n", target);
}
return (int)result;
}
========== end of program.c (partial) ==========
ではビルドして実行してみる。
C ドライブ直下にショートカット「メモ帳」ができた。
ダブルクリックしてみるとメモ帳が起動した。
ショートカットファイルには、リンク先だけでなく
説明や作業ディレクトリなどの色々な情報が格納されているが、
それらも IShellLinkW インタフェースで操作が可能である。