最近遇到需要创建桌面快捷方式,程序结束的时候删除快捷方式的操作,需要用COM编程。记录一下
#include <shlobj.h>
#include<iostream>
#pragma comment(lib, "shell32.lib")
inline std::wstring charToWstring(const char* szIn)
{
int length = MultiByteToWideChar(CP_ACP, 0, szIn, -1, NULL, 0);
WCHAR* buf = new WCHAR[length + 1];
ZeroMemory(buf, (length + 1) * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, szIn, -1, buf, length);
std::wstring strRet(buf);
delete[] buf;
return strRet;
}
//得到当前桌面路径
BOOL GetDesktopPath(char* pszDesktopPath)
{
LPITEMIDLIST ppidl = NULL;
if (SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &ppidl) == S_OK)
{
WCHAR wszClassName[256];
memset(wszClassName, 0, sizeof(wszClassName));
MultiByteToWideChar(CP_ACP, 0, pszDesktopPath, strlen(pszDesktopPath) + 1, wszClassName,
sizeof(wszClassName) / sizeof(wszClassName[0]));
BOOL flag = SHGetPathFromIDList(ppidl, wszClassName);
CoTaskMemFree(ppidl);
sprintf_s(pszDesktopPath,MAX_PATH, "%ws", wszClassName);
return flag;
}
return FALSE;
}
得到快速启动栏的路径
//BOOL GetIEQuickLaunchPath(char* pszIEQueickLaunchPath)
//{
// LPITEMIDLIST ppidl;
//
// if (SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &ppidl) == S_OK)
// {
// WCHAR wszClassName[256];
// memset(wszClassName, 0, sizeof(wszClassName));
// MultiByteToWideChar(CP_ACP, 0, pszIEQueickLaunchPath, strlen(pszIEQueickLaunchPath) + 1, wszClassName,
// sizeof(wszClassName) / sizeof(wszClassName[0]));
// BOOL flag = SHGetPathFromIDList(ppidl, wszClassName);
// strcat_s(pszIEQueickLaunchPath,MAX_PATH, "\\Microsoft\\Internet Explorer\\Quick Launch");
// CoTaskMemFree(ppidl);
// return flag;
// }
//
// return FALSE;
//}
得到 开始->程序组 的路径
//BOOL GetProgramsPath(char* pszProgramsPath)
//{
// LPITEMIDLIST ppidl;
//
// if (SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &ppidl) == S_OK)
// {
// WCHAR wszClassName[256];
// memset(wszClassName, 0, sizeof(wszClassName));
// MultiByteToWideChar(CP_ACP, 0, pszProgramsPath, strlen(pszProgramsPath) + 1, wszClassName,
// sizeof(wszClassName) / sizeof(wszClassName[0]));
// BOOL flag = SHGetPathFromIDList(ppidl, wszClassName);
// CoTaskMemFree(ppidl);
// return flag;
// }
//
// return FALSE;
//}
/*
函数功能:对指定文件在指定的目录下创建其快捷方式
函数参数:
lpszFileName 指定文件,为NULL表示当前进程的EXE文件,也可以直接指定一个目录
lpszLnkFileDir 指定目录,不能为NULL。
lpszLnkFileName 快捷方式名称,为NULL表示EXE文件名。
wHotkey 为0表示不设置快捷键
pszDescription 备注
iShowCmd 运行方式,默认为常规窗口
*/
BOOL CreateFileShortcut(LPCWSTR lpszFileName, LPCSTR lpszLnkFileDir, LPCSTR lpszLnkFileName, LPCSTR lpszWorkDir, WORD wHotkey, LPCTSTR lpszDescription, int iShowCmd = SW_SHOWNORMAL)
{
if (lpszLnkFileDir == NULL)
return FALSE;
HRESULT hr;
IShellLink* pLink; //IShellLink对象指针
IPersistFile* ppf; //IPersisFil对象指针
//创建IShellLink对象
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pLink);
if (FAILED(hr))
return FALSE;
//从IShellLink对象中获取IPersistFile接口
hr = pLink->QueryInterface(IID_IPersistFile, (void**)&ppf);
if (FAILED(hr))
{
pLink->Release();
return FALSE;
}
//我的程序创建的是指定文件,如果要创建的是当前的exe的快捷方式要用下面的
//TCHAR exeFullPath[MAX_PATH]; // MAX_PATH
//GetModuleFileName(NULL, exeFullPath, MAX_PATH); //得到当前的exe文件路径
//pLink->SetPath(exeFullPath);
//目标
pLink->SetPath(lpszFileName);
//工作目录
if (lpszWorkDir != NULL)
{
WCHAR wszClassName[256];
memset(wszClassName, 0, sizeof(wszClassName));
MultiByteToWideChar(CP_ACP, 0, lpszWorkDir, strlen(lpszWorkDir) + 1, wszClassName,
sizeof(wszClassName) / sizeof(wszClassName[0]));
pLink->SetWorkingDirectory(wszClassName);
}
//快捷键
if (wHotkey != 0)
pLink->SetHotkey(wHotkey);
//备注
if (lpszDescription != NULL)
pLink->SetDescription(lpszDescription);
//显示方式
pLink->SetShowCmd(iShowCmd);
//快捷方式的路径 + 名称
char szBuffer[MAX_PATH];
if (lpszLnkFileName != NULL) //指定了快捷方式的名称
sprintf_s(szBuffer,sizeof(szBuffer), "%s\\%s", lpszLnkFileDir, lpszLnkFileName);
else
{
//没有指定名称,就从取指定文件的文件名作为快捷方式名称。
//char *pstr;
char* buf = new char[strlen(lpszFileName) + 1];
strcpy_s(buf,sizeof(buf), lpszFileName);
if (buf == NULL)
{
ppf->Release();
pLink->Release();
return FALSE;
}
//注意后缀名要从.exe改为.lnk
sprintf_s(szBuffer,sizeof(szBuffer), "%s\\%s", lpszLnkFileDir, buf);
int nLen = strlen(szBuffer);
//char lkName = ;
strcat_s(szBuffer,MAX_PATH,".lnk");
}
//保存快捷方式到指定目录下
WCHAR wsz[MAX_PATH]; //定义Unicode字符串
MultiByteToWideChar(CP_ACP, 0, szBuffer, -1, wsz, MAX_PATH);
hr = ppf->Save(wsz, TRUE);
ppf->Release();
pLink->Release();
CoUninitialize(); //释放com接口
return SUCCEEDED(hr);
}
//删除快捷方式
bool DeleteShortcut(LPCSTR lpszShortcut)
{
SHFILEOPSTRUCT fos;
ZeroMemory(&fos, sizeof(fos));
fos.hwnd = HWND_DESKTOP;
fos.wFunc = FO_DELETE;
fos.fFlags = FOF_SILENT | FOF_ALLOWUNDO;
fos.pTo = NULL;
wchar_t temp[MAX_PATH];
wcscpy_s(temp , MAX_PATH,charToWstring(lpszShortcut).c_str());
//注意调用SHFileOperation()函数的时候需要双终止字符串,否则无法获取文件路径
int index;
for (index = 0; index < MAX_PATH; index++)
{
if (temp[index] == L'\0')
break;
}
temp[++index] = L'\0';
fos.pFrom = temp;
// 删除文件夹及其内容
auto hr = SHFileOperation(&fos);
if (hr != 0)
return false;
return true;
}
int main()
{
char szPath[MAX_PATH];
GetDesktopPath(szPath); //得到桌面路径
CreateFileShortcut((L"c:\\"), szPath, "C盘.lnk", NULL, 0, NULL);
//CreateFileShortcut(NULL,"");
strcat_s(szPath, MAX_PATH, "\\C盘.lnk");
DeleteShortcut(szPath);
return 0;
}