#include <windows.h>
#include <shobjidl.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <shellapi.h>
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "shell32.lib")
void RefreshDesktop()
{
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
HWND hDesktop = FindWindow(TEXT("Progman"), NULL);
if (hDesktop)
{
PostMessage(hDesktop, WM_COMMAND, 0x7103, 0);
UpdateWindow(hDesktop);
}
HWND hShellDefView = FindWindowEx(hDesktop, NULL, TEXT("SHELLDLL_DefView"), NULL);
if (hShellDefView)
{
HWND hFolderView = FindWindowEx(hShellDefView, NULL, TEXT("SysListView32"), NULL);
if (hFolderView)
{
RedrawWindow(hFolderView, NULL, NULL,
RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE);
}
}
PostMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)TEXT("Environment"));
}
BOOL GetExeIcon(LPCTSTR szExePath, TCHAR* szIconPath, int* piIconIndex)
{
// 方法1:直接使用程序本身作为图标源
lstrcpy(szIconPath, szExePath);
*piIconIndex = 0;
// 方法2:如果需要备用方案,使用 shell32.dll 中的默认图标
SHFILEINFO sfi = { 0 };
if (!SHGetFileInfo(szExePath, 0, &sfi, sizeof(sfi),
SHGFI_ICON | SHGFI_LARGEICON))
{
lstrcpy(szIconPath, TEXT("%SystemRoot%\\System32\\shell32.dll"));
*piIconIndex = 2; // 默认程序图标
}
if (sfi.hIcon)
{
DestroyIcon(sfi.hIcon);
}
return TRUE;
}
// 修改现有快捷方式的图标
BOOL UpdateShortcutIcon(LPCTSTR szLinkPath, LPCTSTR szIconPath, int iIconIndex)
{
IShellLink* pShellLink = NULL;
IPersistFile* pPersistFile = NULL;
BOOL bSuccess = FALSE;
// 初始化COM
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
return FALSE;
do
{
// 创建ShellLink对象
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (void**)&pShellLink);
if (FAILED(hr))
break;
// 获取IPersistFile接口
hr = pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile);
if (FAILED(hr))
break;
// 加载现有快捷方式
WCHAR wszLinkPath[MAX_PATH] = { 0 };
#ifdef UNICODE
lstrcpyW(wszLinkPath, szLinkPath);
#else
MultiByteToWideChar(CP_ACP, 0, szLinkPath, -1, wszLinkPath, MAX_PATH);
#endif
hr = pPersistFile->Load(wszLinkPath, STGM_READWRITE);
if (FAILED(hr))
break;
// 更新图标
hr = pShellLink->SetIconLocation(szIconPath, iIconIndex);
if (FAILED(hr))
break;
// 保存修改
hr = pPersistFile->Save(wszLinkPath, TRUE);
if (SUCCEEDED(hr))
bSuccess = TRUE;
} while (false);
// 清理
if (pPersistFile)
pPersistFile->Release();
if (pShellLink)
pShellLink->Release();
CoUninitialize();
return bSuccess;
}
BOOL CreateShortcut(LPCTSTR szTargetPath)
{
TCHAR szDesktopPath[MAX_PATH] = { 0 };
TCHAR szFileName[MAX_PATH] = { 0 };
TCHAR szWorkingDir[MAX_PATH] = { 0 };
// 获取目标文件名(不含路径)
lstrcpy(szFileName, PathFindFileName(szTargetPath));
// 获取工作目录(目标程序所在目录)
lstrcpy(szWorkingDir, szTargetPath);
PathRemoveFileSpec(szWorkingDir);
// 获取桌面路径
if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, szDesktopPath)))
{
return FALSE;
}
// 构建快捷方式路径
TCHAR szLinkPath[MAX_PATH] = { 0 };
TCHAR szLinkName[MAX_PATH] = { 0 };
lstrcpy(szLinkName, szFileName);
PathRemoveExtension(szLinkName);
lstrcat(szLinkName, TEXT(".lnk"));
PathCombine(szLinkPath, szDesktopPath, szLinkName);
// 如果快捷方式已存在,直接返回成功
if (PathFileExists(szLinkPath))
{
return TRUE;
}
// 初始化COM
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
return FALSE;
}
IShellLink* pShellLink = NULL;
IPersistFile* pPersistFile = NULL;
BOOL bSuccess = FALSE;
do
{
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (void**)&pShellLink);
if (FAILED(hr))
break;
// 设置目标路径
pShellLink->SetPath(szTargetPath);
// 设置工作目录
pShellLink->SetWorkingDirectory(szWorkingDir);
// 设置描述(可选)
pShellLink->SetDescription(szFileName);
hr = pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile);
if (FAILED(hr))
break;
// 转换为宽字符
WCHAR wszLinkPath[MAX_PATH] = { 0 };
#ifdef UNICODE
lstrcpyW(wszLinkPath, szLinkPath);
#else
MultiByteToWideChar(CP_ACP, 0, szLinkPath, -1, wszLinkPath, MAX_PATH);
#endif
// 保存快捷方式
hr = pPersistFile->Save(wszLinkPath, TRUE);
if (SUCCEEDED(hr))
{
bSuccess = TRUE;
}
} while (false);
// 清理
if (pPersistFile)
pPersistFile->Release();
if (pShellLink)
pShellLink->Release();
CoUninitialize();
return bSuccess;
}
int main(int argc, TCHAR* argv[])
{
if (argc != 2)
{
MessageBox(NULL,
TEXT("用法: ShortcutCreator.exe <程序名称>\n例如: ShortcutCreator.exe MyProgram.exe"),
TEXT("使用说明"),
MB_OK | MB_ICONINFORMATION);
return 1;
}
// 获取程序所在目录
TCHAR szModulePath[MAX_PATH] = { 0 };
TCHAR szCurrentDir[MAX_PATH] = { 0 };
if (!GetModuleFileName(NULL, szModulePath, MAX_PATH))
{
//MessageBox(NULL, TEXT("无法获取程序路径!"), TEXT("错误"), MB_OK | MB_ICONERROR);
return 1;
}
// 提取目录部分
lstrcpy(szCurrentDir, szModulePath);
PathRemoveFileSpec(szCurrentDir);
// 构建完整的目标路径
TCHAR szTargetPath[MAX_PATH] = { 0 };
PathCombine(szTargetPath, szCurrentDir, argv[1]);
// 检查文件是否存在
if (!PathFileExists(szTargetPath))
{
TCHAR szError[MAX_PATH + 100] = { 0 };
wsprintf(szError, TEXT("在程序目录下未找到目标文件:\n%s"), argv[1]);
//MessageBox(NULL, szError, TEXT("错误"), MB_OK | MB_ICONERROR);
return 1;
}
// 检查是否是exe文件
if (lstrcmpi(PathFindExtension(szTargetPath), TEXT(".exe")) != 0)
{
//MessageBox(NULL, TEXT("目标文件必须是exe文件!"), TEXT("错误"), MB_OK | MB_ICONERROR);
return 1;
}
if (CreateShortcut(szTargetPath))
{
RefreshDesktop();
return 0;
}
else
{
//MessageBox(NULL, TEXT("创建快捷方式失败!"), TEXT("错误"), MB_OK | MB_ICONERROR);
return 1;
}
}