bool ShellIO::GetLinkInfo(CString fileName, LinkInfo *linkInfo, int flags) { IShellLink *psl; IPersistFile *ppf; HRESULT hRes; bool ret = false; hRes = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl); if(SUCCEEDED(hRes)) { hRes = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); if(SUCCEEDED(hRes)) { hRes = ppf->Load(fileName.GetBuffer(), NULL); if(SUCCEEDED(hRes)) { wchar_t buf[1000]; if((flags & LI_DESCRIPTION) == LI_DESCRIPTION) { memset(buf, 0, sizeof(buf)); hRes = psl->GetDescription(buf, 1000); if(SUCCEEDED(hRes) && (wcslen(buf) > 0)) { linkInfo->description = buf; ret = true; } else { linkInfo->description.Empty(); } } if((flags & LI_PATH) == LI_PATH) { LPITEMIDLIST pidl; hRes = psl->GetIDList(&pidl); if(SUCCEEDED(hRes) && pidl) { linkInfo->path = PIDLToString(pidl, NULL, SHGDN_FORPARSING); ILFree(pidl); ret = !linkInfo->path.IsEmpty(); } else { linkInfo->path.Empty(); } } if((flags & LI_ARGUMENTS) == LI_ARGUMENTS) { memset(buf, 0, sizeof(buf)); hRes = psl->GetArguments(buf, 1000); if(SUCCEEDED(hRes) && (wcslen(buf) > 0)) { linkInfo->arguments = buf; ret = true; } else { linkInfo->arguments.Empty(); } } if((flags & LI_WORKDIRECTORY) == LI_WORKDIRECTORY) { memset(buf, 0, sizeof(buf)); hRes = psl->GetWorkingDirectory(buf, 1000); if(SUCCEEDED(hRes) && (wcslen(buf) > 0)) { linkInfo->workDirectory = buf; ret = true; } else { linkInfo->workDirectory.Empty(); } } if((flags & LI_ICONLOCATION) == LI_ICONLOCATION) { int iIcon; memset(buf, 0, sizeof(buf)); hRes = psl->GetIconLocation(buf, 1000, &iIcon); if(SUCCEEDED(hRes) && (wcslen(buf) > 0)) { linkInfo->iconLocation = buf; linkInfo->iconIndex = iIcon; ret = true; } else { linkInfo->iconLocation.Empty(); linkInfo->iconIndex = 0; } } } ppf->Release(); } psl->Release(); } return ret; }
// @pymethod str|PyIShellLink|GetDescription|Retrieves the description of the link (displays as Comment in the UI) PyObject *PyIShellLink::GetDescription(PyObject *self, PyObject *args) { IShellLink *pISL = GetI(self); if ( pISL == NULL ) return NULL; // @pyparm int|cchMaxName|1024|Number of character to allocate for the retrieved text int cchMaxName = 1024; if ( !PyArg_ParseTuple(args, "|i:GetDescription", &cchMaxName) ) return NULL; HRESULT hr; TCHAR *pszName = (TCHAR *)malloc(cchMaxName * sizeof(TCHAR) ); if (pszName==NULL) { PyErr_SetString(PyExc_MemoryError, "allocating string buffer"); return NULL; } PY_INTERFACE_PRECALL; hr = pISL->GetDescription( pszName, cchMaxName ); PY_INTERFACE_POSTCALL; PyObject *ret; if ( FAILED(hr) ) ret = OleSetOleError(hr); else ret = PyWinObject_FromTCHAR(pszName); free(pszName); return ret; }
HRESULT ResolveShortcut(const TCHAR* LnkFile, TCHAR* FilePath, TCHAR* LnkDesc, TCHAR* WorkDir) { CoInitialize(NULL); HRESULT hres; IShellLink* psl; WIN32_FIND_DATA wfd; TCHAR strfilepath[MAX_PATH]; TCHAR strlnkdesc[INFOTIPSIZE]; TCHAR strworkdir[MAX_PATH]; USES_CONVERSION; hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *) &psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf); if (SUCCEEDED(hres)) { hres = ppf->Load(LnkFile, STGM_READ); if (SUCCEEDED(hres)) { hres = psl->Resolve(GetDesktopWindow(), 0); if (SUCCEEDED(hres)) { hres = psl->GetPath(strfilepath,MAX_PATH, &wfd, SLGP_UNCPRIORITY ); if (SUCCEEDED(hres)) { _tcscpy(FilePath, strfilepath); hres = psl->GetDescription(strlnkdesc,INFOTIPSIZE); } if (SUCCEEDED(hres)) { _tcscpy(LnkDesc,strlnkdesc); hres = psl->GetWorkingDirectory(strworkdir,MAX_PATH); } if (SUCCEEDED(hres)) { _tcscpy(WorkDir,strworkdir); } } } ppf->Release(); } psl->Release(); } CoUninitialize(); return hres; }
BOOL CInstall::CreateShellLink(LPCSTR description, LPCSTR program, LPCSTR arguments, LPCSTR icon, int nIconIndex) { HRESULT hres; IShellLink* psl; CHAR szLink[MAXSTR]; strcpy(szLink, m_szPrograms); strcat(szLink, "\\"); strcat(szLink, m_szTargetGroup); strcat(szLink, "\\"); strcat(szLink, description); strcat(szLink, ".LNK"); AddMessage("Adding shell link\n "); AddMessage(szLink); AddMessage("\n"); // Ensure string is UNICODE. WCHAR wsz[MAX_PATH]; MultiByteToWideChar(CP_ACP, 0, szLink, -1, wsz, MAX_PATH); // Save old shell link // Get a pointer to the IShellLink interface. hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; // Query IShellLink for the IPersistFile interface. hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf); if (SUCCEEDED(hres)) { // Load the shell link. hres = ppf->Load(wsz, STGM_READ); if (SUCCEEDED(hres)) { // Resolve the link. hres = psl->Resolve(HWND_DESKTOP, SLR_ANY_MATCH); if (SUCCEEDED(hres)) { // found it, so save details CHAR szTemp[MAXSTR]; WIN32_FIND_DATA wfd; int i; fprintf(m_fLogOld, "Name=%s\n", szLink); hres = psl->GetPath(szTemp, MAXSTR, (WIN32_FIND_DATA *)&wfd, SLGP_SHORTPATH ); if (SUCCEEDED(hres)) fprintf(m_fLogOld, "Path=%s\n", szTemp); hres = psl->GetDescription(szTemp, MAXSTR); if (SUCCEEDED(hres)) fprintf(m_fLogOld, "Description=%s\n", szTemp); hres = psl->GetArguments(szTemp, MAXSTR); if (SUCCEEDED(hres) && (szTemp[0] != '\0')) fprintf(m_fLogOld, "Arguments=%s\n", szTemp); hres = psl->GetWorkingDirectory(szTemp, MAXSTR); if (SUCCEEDED(hres) && (szTemp[0] != '\0')) fprintf(m_fLogOld, "Directory=%s\n", szTemp); hres = psl->GetIconLocation(szTemp, MAXSTR, &i); if (SUCCEEDED(hres) && (szTemp[0] != '\0')) { fprintf(m_fLogOld, "IconLocation=%s\n", szTemp); fprintf(m_fLogOld, "IconIndex=%d\n", i); } fprintf(m_fLogOld, "\n"); } } // Release pointer to IPersistFile. ppf->Release(); } // Release pointer to IShellLink. psl->Release(); } // Save new shell link // Get a pointer to the IShellLink interface. hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; // Query IShellLink for the IPersistFile interface for // saving the shell link in persistent storage. hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf); if (SUCCEEDED(hres)) { fprintf(m_fLogNew, "Name=%s\n", szLink); // Set the path to the shell link target. hres = psl->SetPath(program); if (!SUCCEEDED(hres)) AddMessage("SetPath failed!"); fprintf(m_fLogNew, "Path=%s\n", program); // Set the description of the shell link. hres = psl->SetDescription(description); if (!SUCCEEDED(hres)) AddMessage("SetDescription failed!"); fprintf(m_fLogNew, "Description=%s\n", description); if (arguments != (LPCSTR)NULL) { // Set the arguments of the shell link target. hres = psl->SetArguments(arguments); if (!SUCCEEDED(hres)) AddMessage("SetArguments failed!"); fprintf(m_fLogNew, "Arguments=%s\n", arguments); } if (icon != (LPCSTR)NULL) { // Set the arguments of the shell link target. hres = psl->SetIconLocation(icon, nIconIndex); if (!SUCCEEDED(hres)) AddMessage("SetIconLocation failed!"); fprintf(m_fLogNew, "IconLocation=%s\n", icon); fprintf(m_fLogNew, "IconIndex=%d\n", nIconIndex); } // Save the link via the IPersistFile::Save method. hres = ppf->Save(wsz, TRUE); // Release pointer to IPersistFile. ppf->Release(); } // Release pointer to IShellLink. psl->Release(); fprintf(m_fLogNew, "\n"); } return (hres == 0); }
/*! ショートカット(.lnk)の解決 @date 2009.01.08 ryoji CoInitialize/CoUninitializeを削除(WinMainにOleInitialize/OleUninitializeを追加) */ BOOL ResolveShortcutLink( HWND hwnd, LPCTSTR lpszLinkFile, LPTSTR lpszPath ) { BOOL bRes; HRESULT hRes; IShellLink* pIShellLink; IPersistFile* pIPersistFile; WIN32_FIND_DATA wfd; /* 初期化 */ pIShellLink = NULL; pIPersistFile = NULL; *lpszPath = 0; // assume failure bRes = FALSE; // 2009.01.08 ryoji CoInitializeを削除(WinMainにOleInitialize追加) // Get a pointer to the IShellLink interface. // hRes = 0; TCHAR szAbsLongPath[_MAX_PATH]; if( ! ::GetLongFileName( lpszLinkFile, szAbsLongPath ) ){ return FALSE; } // 2010.08.28 DLL インジェクション対策としてEXEのフォルダに移動する CCurrentDirectoryBackupPoint dirBack; ChangeCurrentDirectoryToExeDir(); if( SUCCEEDED( hRes = ::CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&pIShellLink ) ) ){ // Get a pointer to the IPersistFile interface. if( SUCCEEDED(hRes = pIShellLink->QueryInterface( IID_IPersistFile, (void**)&pIPersistFile ) ) ){ // Ensure that the string is Unicode. WCHAR wsz[MAX_PATH]; _tcstowcs(wsz, szAbsLongPath, _countof(wsz)); // MultiByteToWideChar( CP_ACP, 0, lpszLinkFile, -1, wsz, MAX_PATH ); // Load the shortcut. if( SUCCEEDED(hRes = pIPersistFile->Load( wsz, STGM_READ ) ) ){ // Resolve the link. if( SUCCEEDED( hRes = pIShellLink->Resolve(hwnd, SLR_ANY_MATCH ) ) ){ // Get the path to the link target. TCHAR szGotPath[MAX_PATH]; szGotPath[0] = _T('\0'); if( SUCCEEDED( hRes = pIShellLink->GetPath(szGotPath, MAX_PATH, &wfd, SLGP_SHORTPATH ) ) ){ // Get the description of the target. TCHAR szDescription[MAX_PATH]; if( SUCCEEDED(hRes = pIShellLink->GetDescription(szDescription, MAX_PATH ) ) ){ if( _T('\0') != szGotPath[0] ){ /* 正常終了 */ _tcscpy_s( lpszPath, _MAX_PATH, szGotPath ); bRes = TRUE; } } } } } } } // Release the pointer to the IPersistFile interface. if( NULL != pIPersistFile ){ pIPersistFile->Release(); pIPersistFile = NULL; } // Release the pointer to the IShellLink interface. if( NULL != pIShellLink ){ pIShellLink->Release(); pIShellLink = NULL; } // 2009.01.08 ryoji CoUninitializeを削除(WinMainにOleUninitialize追加) return bRes; }
// Resolve a shortcut // Source: https://msdn.microsoft.com/en-us/library/windows/desktop/bb776891%28v=vs.85%29.aspx // // ------> DO NOT FORGET TO CALL CoInitialize first // HRESULT ResolveIt(HWND hwnd, LPCSTR lpszLinkFile, LPWSTR lpszPath, int iPathBufferSize) { IShellLink* psl; HRESULT hres; WCHAR szGotPath[MAX_PATH]; WCHAR szDescription[MAX_PATH]; WIN32_FIND_DATA wfd; *lpszPath = 0; // Assume failure hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); if(SUCCEEDED(hres)) { IPersistFile* ppf; // Get a pointer to the IPersistFile interface. hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); if (SUCCEEDED(hres)) { WCHAR wsz[MAX_PATH]; // Ensure that the string is Unicode. MultiByteToWideChar(CP_ACP, 0, lpszLinkFile, -1, wsz, MAX_PATH); // Add code here to check return value from MultiByteWideChar // for success. // Load the shortcut. hres = ppf->Load(wsz, STGM_READ); if (SUCCEEDED(hres)) { // Resolve the link. hres = psl->Resolve(hwnd, SLR_NO_UI); if (SUCCEEDED(hres)) { // Get the path to the link target. hres = psl->GetPath((LPSTR)szGotPath, MAX_PATH, (WIN32_FIND_DATA*)&wfd, SLGP_SHORTPATH); if (SUCCEEDED(hres)) { // Get the description of the target. hres = psl->GetDescription((LPSTR)szDescription, MAX_PATH); if (SUCCEEDED(hres)) { hres = StringCbCopy((STRSAFE_LPSTR)lpszPath, iPathBufferSize, (STRSAFE_LPSTR)szGotPath); if (SUCCEEDED(hres)) { // Handle success } else { // Handle the error } } } } } // Release the pointer to the IPersistFile interface. ppf->Release(); } // Release the pointer to the IShellLink interface. psl->Release(); } return hres; }
/********************************************* This routine resolves the lnk destination: \param LnkName - The name of the ShortCut\n \param SpecialFolder - where to put the shortcut (See #defines above (MSDN)) \param hwnd - handle of the parent window for MessageBoxes the shell may need to display \param LnkPath - Reference to a CString that receives the linkpath if routine is successful else the string will be empty \param LnkDescription - Reference to a CString that receives the Description of the link else the string will be empty \returns a HRESULT *********************************************/ HRESULT CShortcut::ResolveLink(const CString &LnkName, UINT SpecialFolder, HWND hwnd, CString &LnkPath, CString &LnkDescription) { HRESULT hres; IShellLink* psl; wchar_t *szGotPath = LnkPath.GetBuffer(MAX_PATH); wchar_t *szDescription = LnkDescription.GetBuffer(MAX_PATH); CString sLnkFile, sSpecialFolder; CString sLong; WIN32_FIND_DATA wfd; // get the path to the special folder: if (!GetSpecialFolder(SpecialFolder, sSpecialFolder)) return 1; // return ERROR // build a linkfile: sLnkFile = sSpecialFolder + LnkName + L".lnk"; // Get a pointer to the IShellLink interface. hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*) &psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; // Get a pointer to the IPersistFile interface. hres = psl->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf); if (SUCCEEDED(hres)) { hres = ppf->Load(sLnkFile, STGM_READ); if (SUCCEEDED(hres)) { // Resolve the link. hres = psl->Resolve(hwnd, SLR_ANY_MATCH); if (SUCCEEDED(hres)) { // Get the path to the link target. hres = psl->GetPath(szGotPath, MAX_PATH, (WIN32_FIND_DATA *)&wfd, SLGP_SHORTPATH); LnkPath.ReleaseBuffer(); if (!SUCCEEDED(hres)) { LnkDescription.ReleaseBuffer(); return hres; // application-defined function } // Get the description of the target: hres = psl->GetDescription(szDescription, MAX_PATH); LnkDescription.ReleaseBuffer(); if (!SUCCEEDED(hres)) return hres; } } // Release the pointer to the IPersistFile interface. ppf->Release(); } // Release the pointer to the IShellLink interface. psl->Release(); } // whether OS is <= NT4 or not... use this helper: if (ShortToLongPathName(LnkPath, sLong) > LnkPath.GetLength()) LnkPath = sLong; return hres; }
// http://msdn.microsoft.com/en-us/library/aa969393.aspx bool my_resolveshortcut(TCHAR *linkfile, int size) { bool ok = false; HRESULT hres; IShellLink* psl; WCHAR szGotPath[MAX_PATH]; WCHAR szDescription[MAX_PATH]; WIN32_FIND_DATA wfd; const TCHAR *ext = _tcsrchr (linkfile, '.'); if (!ext || _tcsicmp (ext, _T(".lnk")) != 0) return false; // Get a pointer to the IShellLink interface. It is assumed that CoInitialize // has already been called. hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; // Get a pointer to the IPersistFile interface. hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); if (SUCCEEDED(hres)) { // Add code here to check return value from MultiByteWideChar // for success. // Load the shortcut. hres = ppf->Load(linkfile, STGM_READ); if (SUCCEEDED(hres)) { // Resolve the link. hres = psl->Resolve(NULL, SLR_NO_UI); if (SUCCEEDED(hres)) { // Get the path to the link target. hres = psl->GetPath(szGotPath, MAX_PATH, (WIN32_FIND_DATA*)&wfd, SLGP_SHORTPATH); if (SUCCEEDED(hres)) { // Get the description of the target. hres = psl->GetDescription(szDescription, MAX_PATH); if (SUCCEEDED(hres)) { if (size > 0) my_canonicalize_path (szGotPath, linkfile, size); ok = SUCCEEDED(hres); } } } } // Release the pointer to the IPersistFile interface. ppf->Release(); } // Release the pointer to the IShellLink interface. psl->Release(); } return ok; }
BOOL GetShortcutInfo(LPCTSTR path, CString& targetPath, HICON *largeIcon, HICON *smallIcon, CString *comment) { // Get the attributes of the specified shortcut HRESULT hRes; IShellLink* psl; CString iconFileName; int iconInd; SHFILEINFO inf; hRes = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); if (SUCCEEDED(hRes)) { IPersistFile* ppf; hRes = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); if (SUCCEEDED(hRes)) { #ifndef UNICODE WCHAR wsz[BUFF_SIZE]; MultiByteToWideChar(CP_ACP, 0, path, -1, wsz, BUFF_SIZE); hRes = ppf->Load(wsz, STGM_READ); #else hRes = ppf->Load(path, STGM_READ); #endif } iconInd = 0; hRes = psl->GetPath(targetPath.GetBuffer(BUFF_SIZE), BUFF_SIZE, NULL, SLGP_RAWPATH); targetPath.ReleaseBuffer(); if (!targetPath.IsEmpty()) ExpEnvVars(targetPath); if (largeIcon && smallIcon) { hRes = psl->GetIconLocation(iconFileName.GetBuffer(BUFF_SIZE), BUFF_SIZE, &iconInd); iconFileName.ReleaseBuffer(); if (!iconFileName.IsEmpty()) ExpEnvVars(iconFileName); if (iconFileName.IsEmpty() && targetPath.IsEmpty()) { SHGetFileInfo(path, 0, &inf, sizeof(inf), SHGFI_ICONLOCATION); iconFileName = inf.szDisplayName; iconInd = inf.iIcon; } if (iconFileName.IsEmpty()) { GetFileIcons(targetPath, largeIcon, smallIcon); } else { if (iconInd == -1) iconInd = 0; hRes = ExtractIconEx(iconFileName, iconInd, largeIcon, smallIcon, 1); if (hRes == -1) GetFileIcons(path, largeIcon, smallIcon); } } if (comment) { *comment = GetFileNameComp(path, eFcName); CString descr; hRes = psl->GetDescription(descr.GetBuffer(BUFF_SIZE), BUFF_SIZE); descr.ReleaseBuffer(); if (!descr.IsEmpty()) { if (isdigit(comment->GetAt(0)) && isdigit(comment->GetAt(1))) *comment = EMPTY_CSTR; else *comment += CRLF; *comment += descr; } } ppf->Release(); psl->Release(); } return TRUE; }