오늘은 윈도우 시스템의 바탕화면, quickLaunch, 시작메뉴 에 원하는 실행파일을 위한 단축아이콘 생성에 대한 통합 함수를 설명하고자 합니다.
아래 함수 하나면 원하는 위치에 생성할 수 있습니다. (win10 에서는 안해봐서 될지는 잘.. 해봐야 알 것 같네요..)
이 단축아이콘을 변경되는 경우는 PC을 재부팅해야 설정이 되더라구여..
원래는 아래 함수 후에 시스템에 notify 을 줘야 하는데 그 부분은 검색해 보시면 됩니다.
* 소스코드
// LPTSTR pszFilePath : 실행파일경로 및 파일명.확장자
// LPTSTR pszTitle : \\파일명.lnk
// LPTSTR pszDescription : 표시할 툴팁
// BOOL bDesktop : 바탕화면 생성 유무 TRUE., FALSE
// BOOL bQuickLanch : quicklaunch 생성 유무 TRUE., FALSE
// BOOL bStartMenu : 시작메뉴 생성 유무 TRUE., FALSE
// BOOL bOverWrite : 기존 구성 덮어쓰기 유무 TRUE., FALSE
BOOL Util::CreateShortcut( LPTSTR pszFilePath, LPTSTR pszTitle, LPTSTR pszDescription, BOOL bDesktop, BOOL bQuickLanch, BOOL bStartMenu, BOOL bOverWrite)
{
// D1 ("CShorCutDlg::CreateShortcut() : pszFilePath=%s", pszFilePath);
SHGETFOLDERPATH fnShGetFolderPath;
if( !bDesktop && !bQuickLanch && !bStartMenu ) return TRUE;
HMODULE hModule = LoadLibrary("SHFOLDER.DLL");
if (hModule != NULL){
fnShGetFolderPath = (SHGETFOLDERPATH)GetProcAddress(hModule, "SHGetFolderPathA");
if (fnShGetFolderPath == NULL){
FreeLibrary(hModule);
//MessageBox("아이콘 등록에 실패하였습니다. Shell Version이 낮습니다.", "에러", MB_ICONSTOP);
return FALSE;
}
}
// 실제 대상파일이 존재하는지 체크하는 루틴추가.
//if( !IsFileExist( pszFilePath )) return TRUE;
CString strTempPath;
// 아이콘의 이름 설정이 안되었을 경우 기본 이름으로 설정 : *.exe의 바로가기
if( pszTitle == NULL ) {
TCHAR szFileName[MAX_PATH];
memset( szFileName, 0x00, sizeof(szFileName) );
TCHAR szFilePath[MAX_PATH];
memset( szFilePath, 0x00, sizeof(szFilePath) );
lstrcpy( szFilePath, pszFilePath );
TCHAR *pszToken;
pszToken = strtok( szFilePath, _T("\\"));
while( pszToken != NULL ){
lstrcpy(szFileName, pszToken);
pszToken = strtok(NULL, _T("\\"));
}
strTempPath.Format(_T("\\%s%s"), szFileName, _T("의 바로가기.lnk") );
pszTitle = strTempPath.GetBuffer( strTempPath.GetLength() );
}
BOOL bResult = TRUE;
HRESULT hResult;
IShellLink* pShellLink;
IPersistFile* pPersistFile;
TCHAR szDesktopPath[MAX_PATH];
TCHAR szQuickLanchPath[MAX_PATH];
TCHAR szStartMenuPath[MAX_PATH];
memset( szDesktopPath, 0x00, sizeof(szDesktopPath) );
memset( szQuickLanchPath, 0x00, sizeof(szQuickLanchPath) );
memset( szStartMenuPath, 0x00, sizeof(szStartMenuPath) );
// 바탕화면 아이콘이 저장될 경로 설정
//SHGetSpecialFolderPath(NULL, szDesktopPath, MAX_PATH );
if( FAILED( fnShGetFolderPath(NULL, CSIDL_DESKTOP , NULL, 0, szDesktopPath) ) ) return FALSE;
LPSTR strDesktopPath = lstrcat( szDesktopPath, pszTitle );
// 빠른 실행 아이콘이 저장될 경로 설정
if( FAILED( fnShGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, szQuickLanchPath) ) ) return FALSE;
LPSTR strQuickLanchPath = lstrcat( szQuickLanchPath, _T("\\Microsoft\\Internet Explorer\\Quick Launch") );
strQuickLanchPath = lstrcat( szQuickLanchPath, pszTitle );
// 시작메뉴
if( FAILED( fnShGetFolderPath(NULL, CSIDL_PROGRAMS, NULL, 0, szStartMenuPath) ) ) return FALSE;
LPSTR strStartMenuPath = lstrcat( szStartMenuPath, pszTitle );
if( !bOverWrite ){
// 바탕화면 아이콘이 있으면
if( IsFileExist( (LPCTSTR)strDesktopPath ) ) bDesktop = FALSE;
// 빠른실행 아이콘이 있으면
if( IsFileExist( (LPCTSTR)szQuickLanchPath ) ) bQuickLanch = FALSE;
// 시작메뉴 아이콘이 있으면
if( IsFileExist( (LPCTSTR)szStartMenuPath ) ) bStartMenu = FALSE;
if( !bDesktop && !bQuickLanch && !bStartMenu ) return TRUE;
}
// COM Object 초기화
CoInitialize(NULL);
// IShellLink 객체를 생성하고 포인터를 구함
hResult = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*) &pShellLink);
if( SUCCEEDED(hResult) ){
// 단축아이콘의 대상체와 설명을 설정한다.
CString exe_dir_str;
TCHAR drive[_MAX_DRIVE] = _T(""), dir[_MAX_DIR] = _T("");
TCHAR fname[_MAX_FNAME] = _T(""), ext[_MAX_EXT] = _T("");
_tsplitpath( pszFilePath, drive, dir, fname, ext );
exe_dir_str.Format("%s%s", drive, dir);
pShellLink->SetPath( pszFilePath );
pShellLink->SetDescription( pszDescription );
pShellLink->SetArguments(_T(""));
pShellLink->SetWorkingDirectory( exe_dir_str );
// 저장하기 위해 IPersistFile 객체 생성
hResult = pShellLink->QueryInterface( IID_IPersistFile, (LPVOID *) &pPersistFile );
// 유니코드로 파일 패스를 변경한 후 저장
if( SUCCEEDED(hResult) ){
WORD wszDesktop[MAX_PATH];
memset( wszDesktop, 0x00, sizeof(wszDesktop) );
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, strDesktopPath, -1, LPWSTR(wszDesktop), MAX_PATH );
WORD wszQuickLanch[MAX_PATH];
memset( wszQuickLanch, 0x00, sizeof(wszQuickLanch) );
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, strQuickLanchPath, -1, LPWSTR(wszQuickLanch), MAX_PATH );
WORD wszStartMenu[MAX_PATH];
memset( wszStartMenu, 0x00, sizeof(wszStartMenu) );
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, strStartMenuPath, -1, LPWSTR(wszStartMenu), MAX_PATH );
// shortcut 등록
if( bDesktop ){
if( !pPersistFile->Save( LPWSTR(wszDesktop), TRUE ) ) bResult = FALSE;
}
//Quick Lauch에 등록
if( bQuickLanch ){
if( !pPersistFile->Save( LPWSTR(wszQuickLanch), TRUE ) ) bResult = FALSE;
}
//bStartMenu에 등록
if( bStartMenu ){
if( !pPersistFile->Save( LPWSTR(wszStartMenu), TRUE ) ) bResult = FALSE;
}
pPersistFile->Release();
// 아이콘 재설정
::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST | SHCNF_FLUSH, NULL, NULL);
}
pShellLink->Release();
//COM 해제
CoUninitialize();
FreeLibrary(hModule);
return bResult;
}else{
FreeLibrary(hModule);
}
return bResult;
}
* 사용법
BOOL ret = CreateShortcut( "c:\\실행폴더\\aaa.exe", "\\aaa.lnk", "테스트입니다.", TRUE, TRUE, TRUE, TRUE);
c:\\실행폴더\\aaa.exe 파일을 위한 단축아이콘 생성을 위한 것으로 aaa.lnk 는 단축아이콘 생성이름입니다. 보통 실행파일명으로 해주면 됩니다.
바탕화면, quicklaunch, startmenu 에 단축아이콘을 생성하고. 기존것이 있다면 덮어쓴다는 의미 입니다.
저는 위 함수 하나로 사용하고 있습니다.