実行ファイルへのショートカットをバッチファイルから作成する方法を紹介します。
ショートカットを作成する機能は ShellLink オブジェクトによって提供されています。ShellLink オブジェクトは Windows Scripting Host (WSH) からも呼び出せるので、 VBScript (VBS) や JScript でショートカット作成コマンドを実装することもできるのですが、 今回は C++を使って実行ファイル (EXE) としてショートカット作成コマンドを実装してみました。
C++から ShellLink を使う方法はマイクロソフトのサイトで丁寧に解説されています。
上記を参考に実装したソースコード shortcut.cpp
がこちらです。
shortcut.cpp#include <windows.h>
#include <tchar.h>
#include <locale.h>
#include <shobjidl.h>
#include <shlguid.h>
#pragma comment(lib, "ole32.lib")
LPTSTR get_message(HRESULT hr)
{
LPTSTR msg;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
hr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&msg,
0,
NULL);
return msg;
}
int _tmain(int argc, TCHAR* argv[])
{
TCHAR filepath[MAX_PATH];
TCHAR linkpath[MAX_PATH];
IShellLink* pShellLink = NULL;
IPersistFile* pPersistFile = NULL;
HRESULT hr;
LPTSTR msg = NULL;
int return_code = 0;
_tsetlocale(LC_ALL, _T(""));
if(argc != 3)
{
_tprintf(
_T("usage: shortcut.exe <filepath> <linkpath>¥n")
_T("¥n")
_T("Special Folders¥n")
_T(" Desktop = %%USERPROFILE%%¥¥Desktop¥n")
_T(" Startup(user) = %%APPDATA%%¥¥Microsoft¥¥Windows¥¥Start Menu¥¥Programs¥¥Startup¥n")
_T(" Startup(all users) = %%ALLUSERSPROFILE%%¥¥Microsoft¥¥Windows¥¥Start Menu¥¥Programs¥¥Startup¥n")
_T("¥n")
_T("Example¥n")
_T(" shortcut.exe ¥"C:¥¥Windows¥¥System32¥¥notepad.exe¥" ¥"%%USERPROFILE%%¥¥Desktop¥¥notepad.lnk¥"¥n")
);
return_code = 1;
goto EXIT;
}
if(GetFullPathName(argv[1], MAX_PATH, filepath, NULL) == 0)
{
DWORD e = GetLastError();
_tprintf(_T("FAILED: GetFullPathName(¥"%s¥"): %d: %s¥n"),
argv[1], e, msg = get_message(e));
return_code = 2;
goto EXIT;
}
if(GetFullPathName(argv[2], MAX_PATH, linkpath, NULL) == 0)
{
DWORD e = GetLastError();
_tprintf(_T("FAILED: GetFullPathName(¥"%s¥"): %d: %s¥n"),
argv[2], e, msg = get_message(e));
return_code = 3;
goto EXIT;
}
hr = CoInitialize(NULL);
if(FAILED(hr))
{
_tprintf(_T("FAILED: CoInitialize: 0x%08x: %s¥n"),
hr, msg = get_message(hr));
return_code = 3;
goto EXIT;
}
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (LPVOID*)&pShellLink);
if(hr != S_OK)
{
_tprintf(_T("FAILED: CoCreateInstance(CLSID_ShellLink): 0x%08x: %s¥n"),
hr, msg = get_message(hr));
return_code = 4;
goto EXIT;
}
hr = pShellLink->SetPath(filepath);
if(hr != S_OK)
{
_tprintf(_T("FAILED: IShellLink::SetPath(¥"%s¥"): 0x%08x: %s¥n"),
filepath, hr, msg = get_message(hr));
return_code = 5;
goto EXIT;
}
hr = pShellLink->QueryInterface(IID_IPersistFile, (LPVOID*)&pPersistFile);
if(hr != S_OK)
{
_tprintf(_T("FAILED: IShellLink::QueryInterface(IID_IPersistFile): 0x%08x: %s¥n"),
hr, msg = get_message(hr));
return_code = 6;
goto EXIT;
}
hr = pPersistFile->Save((LPCOLESTR)linkpath, TRUE);
if(hr != S_OK)
{
_tprintf(_T("FAILED: IPersistFile::Save(¥"%s¥"): 0x%08x: %s¥n"),
linkpath, hr, msg = get_message(hr));
return_code = 7;
goto EXIT;
}
_tprintf(_T("%s -> %s¥n"), linkpath, filepath);
EXIT:
if(msg != NULL)
{
LocalFree(msg);
}
if(pPersistFile != NULL)
{
pPersistFile->Release();
}
if(pShellLink != NULL)
{
pShellLink->Release();
}
CoUninitialize();
return return_code;
}
TCHAR
を使っていますが、 TCHAR
= WCHAR
と決め打ちしている部分があるので ANSI 版としてビルドすることはできません。-DUNICODE
と -D_UNICODE
を指定して UNICODE 版としてビルドしてください。ole32.lib
のリンクも必要ですが、 これはソースコード内の #pragma comment
で指定しているのでコマンドラインでの指定は不要です。
以下のコマンドでコンパイルできます。
コマンドプロンプトC:¥>cl.exe -DUNICODE -D_UNICODE shortcut.cpp
- C/C++コンパイラー
- C/C++コンパイラー (
cl.exe
) は Visual Studio (VC++)、 Windows SDK、 Windows Driver Kit などに含まれています。Windows Driver Kit 7.1 のインストール手順について記事を書いたことがあります。参考にしてください。
👉 WDK 7.1 を使って Visual C++再頒布可能パッケージを必要としない実行ファイルをビルドする
ビルド済みのバイナリはこちらからダウンロードできます。
使い方
shortcut.exe
に 2 つの引数を指定します。第 1 引数は実体であるファイルのパス、 第 2 引数はショートカットを作成するパスです。ショートカットのパスの末尾は .lnk
としてください。
第 1 引数、 第 2 引数ともに相対パスを指定することができます。相対パスを指定した場合、 shortcut.exe
を実行したときのカレントディレクトリを基準に相対パスが解決されます。絶対パスを指定するほうが分かりやすいです。
パス指定には特殊フォルダーを示す環境変数を使うこともできます。(環境変数の展開機能は shortcut.exe
ではなく cmd.exe
シェルによるものです。) たとえば、 デスクトップを指定する場合は %USERPROFILE%\Desktop\
が使用できます。
主な特殊フォルダー | パス |
---|---|
デスクトップ | %USERPROFILE%\Desktop |
スタートアップ (個人) | %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup |
スタートアップ (すべてのユーザー) | %ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs\Startup |
notepad.exe
へのショートカットを 「メモ帳」 という名前でデスクトップに作成する場合は以下のようにします。
コマンドプロンプトC:¥>shortcut.exe "C:¥Windows¥System32¥notepad.exe" "%USERPROFILE%¥Desktop¥メモ帳.lnk"
引数を指定せずに shortcut.exe
を実行すると簡単な説明が表示されます。
コマンドプロンプトC:¥>shortcut.exe usage: shortcut.exe <filepath> <linkpath> Special Folders Desktop = %USERPROFILE%¥Desktop Startup(user) = %APPDATA%¥Microsoft¥Windows¥Start Menu¥Programs¥Startup Startup(all users) = %ALLUSERSPROFILE%¥Microsoft¥Windows¥Start Menu¥Programs¥Startup Example shortcut.exe "C:¥Windows¥System32¥notepad.exe" "%USERPROFILE%¥Desktop¥notepad.lnk"
ショートカット作成コマンド shortcut.exe
の紹介は以上です。