Visual C++ 7.1Visual C++ 7.0Windows 2003Windows 2000Visual C++ 6.0Windows XP中级开发Visual StudioWindowsC++
如何创建和解析快捷方式






4.62/5 (33投票s)
本文档提供了两个现成的函数,用于创建和解析快捷方式。
引言
快捷方式是具有.lnk扩展名的文件。这些文件中的每一个都包含一个特殊的COM对象,指向另一个文件。通常,当你尝试打开一个.lnk文件时,系统会打开该快捷方式指向的文件。
让我们做一个实验。在某个地方创建一个文本文件(具有.txt扩展名的文件)。然后创建一个指向该文件的快捷方式(如果你不知道如何手动创建快捷方式,请给我发送私人电子邮件)。然后尝试使用Microsoft Word打开该快捷方式,使用文件->打开命令并仅选择刚刚创建的快捷方式。MS Word会正确执行:它将打开该快捷方式指向的文本文件。现在使用记事本执行相同的操作。你将看到乱码,而不是文本文件的内容。这意味着记事本不知道如何处理快捷方式。
因此我们得出结论:在Windows中,程序必须内置对快捷方式的支持,才能正确处理它们。
在本文中,我将展示如何做到这一点。我将展示两个函数:如何创建和解析快捷方式。代码注释良好(我认为)并且不言自明。
代码
/********************************************************************** * Function......: CreateShortcut * Parameters....: lpszFileName - string that specifies a valid file name * lpszDesc - string that specifies a description for a shortcut * lpszShortcutPath - string that specifies a path and file name of a shortcut * Returns.......: S_OK on success, error code on failure * Description...: Creates a Shell link object (shortcut) **********************************************************************/ HRESULT CreateShortcut(/*in*/ LPCTSTR lpszFileName, /*in*/ LPCTSTR lpszDesc, /*in*/ LPCTSTR lpszShortcutPath) { HRESULT hRes = E_FAIL; DWORD dwRet = 0; CComPtr<IShellLink> ipShellLink; // buffer that receives the null-terminated string // for the drive and path TCHAR szPath[MAX_PATH]; // buffer that receives the address of the final //file name component in the path LPTSTR lpszFilePart; WCHAR wszTemp[MAX_PATH]; // Retrieve the full path and file name of a specified file dwRet = GetFullPathName(lpszFileName, sizeof(szPath) / sizeof(TCHAR), szPath, &lpszFilePart); if (!dwRet) return hRes; // Get a pointer to the IShellLink interface hRes = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&ipShellLink); if (SUCCEEDED(hRes)) { // Get a pointer to the IPersistFile interface CComQIPtr<IPersistFile> ipPersistFile(ipShellLink); // Set the path to the shortcut target and add the description hRes = ipShellLink->SetPath(szPath); if (FAILED(hRes)) return hRes; hRes = ipShellLink->SetDescription(lpszDesc); if (FAILED(hRes)) return hRes; // IPersistFile is using LPCOLESTR, so make sure // that the string is Unicode #if !defined _UNICODE MultiByteToWideChar(CP_ACP, 0, lpszShortcutPath, -1, wszTemp, MAX_PATH); #else wcsncpy(wszTemp, lpszShortcutPath, MAX_PATH); #endif // Write the shortcut to disk hRes = ipPersistFile->Save(wszTemp, TRUE); } return hRes; } /********************************************************************* * Function......: ResolveShortcut * Parameters....: lpszShortcutPath - string that specifies a path and file name of a shortcut * lpszFilePath - string that will contain a file name * Returns.......: S_OK on success, error code on failure * Description...: Resolves a Shell link object (shortcut) *********************************************************************/ HRESULT ResolveShortcut(/*in*/ LPCTSTR lpszShortcutPath, /*out*/ LPTSTR lpszFilePath) { HRESULT hRes = E_FAIL; CComPtr<IShellLink> ipShellLink; // buffer that receives the null-terminated string // for the drive and path TCHAR szPath[MAX_PATH]; // buffer that receives the null-terminated // string for the description TCHAR szDesc[MAX_PATH]; // structure that receives the information about the shortcut WIN32_FIND_DATA wfd; WCHAR wszTemp[MAX_PATH]; lpszFilePath[0] = '\0'; // Get a pointer to the IShellLink interface hRes = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&ipShellLink); if (SUCCEEDED(hRes)) { // Get a pointer to the IPersistFile interface CComQIPtr<IPersistFile> ipPersistFile(ipShellLink); // IPersistFile is using LPCOLESTR, // so make sure that the string is Unicode #if !defined _UNICODE MultiByteToWideChar(CP_ACP, 0, lpszShortcutPath, -1, wszTemp, MAX_PATH); #else wcsncpy(wszTemp, lpszShortcutPath, MAX_PATH); #endif // Open the shortcut file and initialize it from its contents hRes = ipPersistFile->Load(wszTemp, STGM_READ); if (SUCCEEDED(hRes)) { // Try to find the target of a shortcut, // even if it has been moved or renamed hRes = ipShellLink->Resolve(NULL, SLR_UPDATE); if (SUCCEEDED(hRes)) { // Get the path to the shortcut target hRes = ipShellLink->GetPath(szPath, MAX_PATH, &wfd, SLGP_RAWPATH); if (FAILED(hRes)) return hRes; // Get the description of the target hRes = ipShellLink->GetDescription(szDesc, MAX_PATH); if (FAILED(hRes)) return hRes; lstrcpyn(lpszFilePath, szPath, MAX_PATH); } } } return hRes; }
使用代码
以下代码将展示如何使用这些函数。
void HowToCreateShortcut() { LPCTSTR lpszFileName = _T("C:\\Work\\Window.exe"); LPCTSTR lpszShortcutDesc = _T("Anything can go here"); LPCTSTR lpszShortcutPath = _T("C:\\Documents and Settings\\Administrator\\Desktop\\Sample Shortcut.lnk"); CreateShortcut(lpszFileName, lpszShortcutDesc, lpszShortcutPath); } void HowToResolveShortcut() { LPCTSTR lpszShortcutPath = _T("C:\\Documents and Settings\\Administrator\\Desktop\\Sample Shortcut.lnk"); TCHAR szFilePath[MAX_PATH]; ResolveShortcut(lpszShortcutPath, szFilePath); }
就是这样。