Microsoft のドキュメントに、インターネットショートカットの作成方法が 記述されていますし、ショートカットのアイコンの変更方法もあります。 しかし、非常に簡単にしか書かれておらず、ショートカット作成に関しては「これと同じようにしなさい」と言わんばかりではあります。 確かに、インターネットショートカットの作成方法が理解できるのであれば、 ショートカット作成は難しくありませんが、Shell Interfaces や COM Interfaces の 英文記述のマニュアルの場所を知っている必要があります。 で、サンプルをまとめてみました。 ブラウザでダウンロード 呼び出し部分ソースを3つに分けました 1) 呼び出し部分( _tWinMain ) 2) インターネットショートカットの作成 3) ショートカットの作成 ※ ファイルのパスの処理が少し面倒なので、lightbox.lib を使用しました create_shortcut.exe を実行すると、デスクトップに winofsql.jp のリンクと dir を実行して pause するコマンドプロンプトのショートカットが作成されます。 #define _WIN32_WINNT 0x0500 #include <tchar.h> #include "lightbox\lightbox.h" #pragma comment( lib, "lightbox\\lightbox.lib" ) #pragma comment( lib, "shlwapi.lib" ) HRESULT CreateShortcutToURL(LPCSTR pszURL, LPCSTR pszLinkFile); HRESULT CreateShortcut( LPCSTR pszLink, LPCSTR pszLinkFile, LPCSTR pszArguments=NULL, LPCSTR pszDescription=NULL, LPCSTR pszWorkingDirectory=NULL, int nSetShowCmd=SW_SHOWNORMAL, WORD wHotkey=0, LPCSTR pszIcon=NULL, int iIcon=0 ); // ********************************************************* // Windows アプリケーションとしてのエントリポイント // Link.exe で /SUBSYSTEM:WINDOWS がデフォルトで // 指定される事になります // ********************************************************* int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow ) { HRESULT hRet; char buff[MAX_PATH]; char file[MAX_PATH]; hRet = SHGetSpecialFolderPath( NULL, buff, CSIDL_DESKTOPDIRECTORY, false ); lstrcpy( file, buff ); lstrcat( file, "\\winofsql.url" ); // COM 利用時に必要 CoInitialize(NULL); // URL ショートカットをデスクトップに作成 hRet = CreateShortcutToURL( "http://winofsql.jp", file ); if ( SUCCEEDED(hRet) ) { // 成功処理 } LboxString exeFile, exePath; exeFile = "cmd.exe"; LboxInfo Info; Info.SearchFromPath( exeFile, exePath ); lstrcpy( file, buff ); lstrcat( file, "\\コマンドプロンプト.lnk" ); WORD wHotkey = MAKEWORD(VK_F9,HOTKEYF_CONTROL); hRet = CreateShortcut( exePath.szLboxString, file, "/c dir & pause", "dir 実行後一時停止", NULL, SW_SHOWNORMAL, wHotkey ); if ( SUCCEEDED(hRet) ) { // 成功処理 } // COM 利用終了時に必要 CoUninitialize(); return 0; } icon の設定はしていませんが、その他の設定可能な内容は全てプログラムで 処理されています。icon も、引数で渡せば処理されます。 HRESULT CreateShortcut( LPCSTR pszLink, LPCSTR pszLinkFile, LPCSTR pszArguments=NULL, LPCSTR pszDescription=NULL, LPCSTR pszWorkingDirectory=NULL, int nSetShowCmd=SW_SHOWNORMAL, WORD wHotkey=0, LPCSTR pszIcon=NULL, int iIcon=0 ); pszLink 実行プログラムのパス。 フルパスでなくても、OS が補完してくれるが、 作業ディレクトリをの自動取得させる為に SearchFromPath を使用して設定しています。 pszLinkFile ショートカットが作成されるパス pszArguments 引数 pszDescription コメント pszWorkingDirectory 作業ディレクトリ nSetShowCmd 実行時の大きさ wHotkey LOWORD が仮想キーコード HIWORD が以下 HOTKEYF_ALT ALT key HOTKEYF_CONTROL CTRL key HOTKEYF_EXT Extended key HOTKEYF_SHIFT SHIFT key pszIcon アイコンを持つファイルへのパス iIcon 含まれるアイコンの番号 この処理では、icon を指定せずに省略して呼び出しています ( デフォルト指定による引数の省略 : 途中省略は不可 ) CreateShortcutToURLMicrosoft のサンプルから、WCHAR の処理を簡単にする為に _bstr_t を使用しています。 何故か Microsoft は、MultiByteToWideChar を使用したサンプルばかりのような 気がしますが、どう考えても _bstr_t を使用すべきです。 // ********************************************************* // URL ショートカットをデスクトップに作成 // ********************************************************* #define _WIN32_WINNT 0x0500 #include <tchar.h> #include "lightbox\lightbox.h" #include <intshcut.h> #pragma comment( lib, "lightbox\\lightbox.lib" ) #pragma comment( lib, "shlwapi.lib" ) HRESULT CreateShortcutToURL(LPCSTR pszURL, LPCSTR pszLinkFile) { HRESULT hRes; IUniformResourceLocator *pURL = NULL; // オブジェクト作成 hRes = CoCreateInstance ( CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER, IID_IUniformResourceLocator, (LPVOID*) &pURL ); // 成功処理 if ( SUCCEEDED( hRes ) ) { IPersistFile *pPF = NULL; hRes = pURL->SetURL(pszURL, 0); if ( SUCCEEDED(hRes) ) { _bstr_t path = pszLinkFile; hRes = pURL->QueryInterface( IID_IPersistFile, (void **)&pPF ); if ( SUCCEEDED(hRes) ) { hRes = pPF->Save((wchar_t *)path, TRUE); pPF->Release (); } } pURL->Release (); } return hRes; } CreateShortcutソースを見やすくする為に、エラー処理をはしょりましたが、 エラーが出無いような引数を渡すバッチ処理用を想定していますので、 特に問題は無いと思います。 // ********************************************************* // ショートカットをデスクトップに作成 // ********************************************************* #define _WIN32_WINNT 0x0500 #include <tchar.h> #include "lightbox\lightbox.h" #include <intshcut.h> #pragma comment( lib, "lightbox\\lightbox.lib" ) #pragma comment( lib, "shlwapi.lib" ) HRESULT CreateShortcut( LPCSTR pszLink, LPCSTR pszLinkFile, LPCSTR pszArguments=NULL, LPCSTR pszDescription=NULL, LPCSTR pszWorkingDirectory=NULL, int nSetShowCmd=SW_SHOWNORMAL, WORD wHotkey=0, LPCSTR pszIcon=NULL, int iIcon=0 ) { HRESULT hRes; IShellLink *pLink = NULL; char szWorkingDirectory[MAX_PATH]; // オブジェクト作成 hRes = CoCreateInstance ( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*) &pLink ); // 成功処理 if ( SUCCEEDED( hRes ) ) { IPersistFile *pPF = NULL; hRes = pLink->SetPath(pszLink); if ( SUCCEEDED(hRes) ) { // 本来は、全てのメソッドで結果をチェックすべきですが、 // 意味を読み取りやすくする為に省略しています if ( pszArguments != NULL ) { // 引数 hRes = pLink->SetArguments(pszArguments); } if ( pszDescription != NULL ) { // コメント hRes = pLink->SetDescription(pszDescription); } if ( pszIcon != NULL ) { // コメント hRes = pLink->SetIconLocation(pszIcon,iIcon); } if ( wHotkey != 0 ) { // コメント hRes = pLink->SetHotkey(wHotkey); } if ( pszWorkingDirectory != NULL ) { // 作業フォルダ lstrcpy( szWorkingDirectory, pszWorkingDirectory ); } else { // 作業フォルダ // lightbox.lib 使用 // http://winofsql.jp/VA003334/cmstd040521004209.htm#ttl19 LboxString LString = (LPTSTR)pszLink; LString.RemoveFileSpec(); lstrcpy( szWorkingDirectory, LString.szLboxString ); } hRes = pLink->SetWorkingDirectory( szWorkingDirectory ); // 実行時の大きさ hRes = pLink->SetShowCmd(nSetShowCmd); _bstr_t path = pszLinkFile; hRes = pLink->QueryInterface( IID_IPersistFile, (void **)&pPF ); if ( SUCCEEDED(hRes) ) { hRes = pPF->Save((wchar_t *)path, TRUE); pPF->Release(); } } pLink->Release(); } return hRes; } |