// Creates a shell link (a.k.a. shortcut) located at swzLinkFile that points to
// szTargetFile with a description of szDescription.
BOOL CreateLink(LPCTSTR szTargetFile, LPCTSTR szDescription, LPCOLESTR swzLinkFile)
{
BOOL bRet = FALSE;
IShellLink* psl;
HRESULT hr =::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (void**) &psl);
if (SUCCEEDED(hr))
{
IPersistFile* ppf;
hr = psl->QueryInterface(IID_IPersistFile, (void**) &ppf);
if (SUCCEEDED(hr))
{
hr = psl->SetPath(szTargetFile);
if (SUCCEEDED(hr))
{
hr = psl->SetDescription(szDescription);
if (SUCCEEDED(hr))
{
hr = ppf->Save(swzLinkFile, TRUE);
if (SUCCEEDED(hr))
{
bSuccess = TRUE;
}
}
}
ppf->Release();
}
psl->Release();
}
return bSuccess;
}
// NOTE: Hardcoding C:\WINDOWS and C:\Program Files is a bad practice. Use
// something like ::SHGetFolderPath().
BOOL bSuccess = CreateLink
(
_T("C:\\WINDOWS\\SYSTEM32\\SOL.EXE"),
_T("Shortcut to SOL.EXE"),
L"C:\\Program Files\\sol.lnk")
);
One might expect that the creation of the file C:\Program Files\sol.lnk would be silently redirected by Vista using file virtualization and CreateLink() would succeed, but it doesn’t — the call to IPersistFile::Save() returns E_ACCESSDENIED.