/* リンク あらかじめ、CoInitialize(NULL); を実行しておくこと src ... old_path dest ... new_path */ BOOL SymLinkW(WCHAR *src, WCHAR *dest, WCHAR *arg) { IShellLinkW *shellLink; IPersistFile *persistFile; WCHAR *ps_dest = dest; BOOL ret = FALSE; WCHAR buf[MAX_PATH]; if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void **)&shellLink))) { shellLink->SetPath(src); shellLink->SetArguments(arg); GetParentDirW(src, buf); shellLink->SetWorkingDirectory(buf); if (SUCCEEDED(shellLink->QueryInterface(IID_IPersistFile, (void **)&persistFile))) { if (SUCCEEDED(persistFile->Save(ps_dest, TRUE))) { ret = TRUE; GetParentDirW(dest, buf); ::SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATHW|SHCNF_FLUSH, buf, NULL); } persistFile->Release(); } shellLink->Release(); } return ret; }
void MusicRegeditManager::setFileLink(const QString &src, const QString &des, const QString &ico, const QString &args, const QString &description) { #ifdef Q_OS_WIN HRESULT hres = CoInitialize(nullptr); if(SUCCEEDED(hres)) { IShellLinkW *psl = nullptr; hres = CoCreateInstance(CLSID_ShellLink, nullptr, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); if(SUCCEEDED(hres)) { IPersistFile *ppf; if(!src.isEmpty()) { psl->SetPath(src.toStdWString().c_str()); } if(!ico.isEmpty()) { psl->SetIconLocation(ico.toStdWString().c_str(), 0); } if(!args.isEmpty()) { psl->SetArguments(args.toStdWString().c_str()); } if(!description.isEmpty()) { psl->SetDescription(description.toStdWString().c_str()); } hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf); if(SUCCEEDED(hres)) { ppf->Save(des.toStdWString().c_str(), FALSE); ppf->Release(); } psl->Release(); } } #else QFile file(":/ext/desktop"); if(file.open(QFile::ReadOnly)) { QByteArray data(file.readAll()); file.close(); data.append(QString("Icon=%1\n").arg(ico)); data.append(QString("Exec=%1\n").arg(ico + src)); data.append(QString("Path=%1\n").arg(args)); file.setFileName(des + "/" + description + ".desktop"); if(file.open(QFile::WriteOnly)) { file.write(data); file.close(); QProcess::execute("chmod", QStringList() << "+x" << file.fileName()); } } #endif }
void Win32TaskbarManager::addRecent(const Common::String &name, const Common::String &description) { //warning("[Win32TaskbarManager::addRecent] Adding recent list entry: %s (%s)", name.c_str(), description.c_str()); if (_taskbar == NULL) return; // ANSI version doesn't seem to work correctly with Win7 jump lists, so explicitly use Unicode interface. IShellLinkW *link; // Get the ScummVM executable path. WCHAR path[MAX_PATH]; GetModuleFileNameW(NULL, path, MAX_PATH); // Create a shell link. if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC, IID_IShellLinkW, reinterpret_cast<void **> (&link)))) { // Convert game name and description to Unicode. LPWSTR game = ansiToUnicode(name.c_str()); LPWSTR desc = ansiToUnicode(description.c_str()); // Set link properties. link->SetPath(path); link->SetArguments(game); Common::String iconPath = getIconPath(name); if (iconPath.empty()) { link->SetIconLocation(path, 0); // No game-specific icon available } else { LPWSTR icon = ansiToUnicode(iconPath.c_str()); link->SetIconLocation(icon, 0); delete[] icon; } // The link's display name must be set via property store. IPropertyStore* propStore; HRESULT hr = link->QueryInterface(IID_IPropertyStore, reinterpret_cast<void **> (&(propStore))); if (SUCCEEDED(hr)) { PROPVARIANT pv; pv.vt = VT_LPWSTR; pv.pwszVal = desc; hr = propStore->SetValue(PKEY_Title, pv); propStore->Commit(); propStore->Release(); } // SHAddToRecentDocs will cause the games to be added to the Recent list, allowing the user to pin them. SHAddToRecentDocs(SHARD_LINK, link); link->Release(); delete[] game; delete[] desc; } }
HRESULT CTaskbar7::AddRecent(BSTR name, BSTR path, BSTR arguments, BSTR icon) { USES_CONVERSION; // ANSI version doesn't seem to work correctly with Win7 jump lists, so explicitly use Unicode interface. IShellLinkW *pShellLink = NULL; IPropertyStore *pPropertyStore = NULL; PROPVARIANT propVariant; HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pShellLink)); EXIT_ON_ERROR(hr); // Path hr = pShellLink->SetPath(path); EXIT_ON_ERROR(hr); // Arguments hr = pShellLink->SetArguments(arguments); EXIT_ON_ERROR(hr); // Icon Location hr = pShellLink->SetIconLocation(wstring(icon).empty() ? path : icon, 0); EXIT_ON_ERROR(hr); hr = pShellLink->QueryInterface(IID_PPV_ARGS(&pPropertyStore)); EXIT_ON_ERROR(hr); // Name hr = InitPropVariantFromString(name, &propVariant); EXIT_ON_ERROR(hr); hr = pPropertyStore->SetValue(PKEY_Title, propVariant); EXIT_ON_ERROR(hr); hr = pPropertyStore->Commit(); EXIT_ON_ERROR(hr); // SHAddToRecentDocs will cause the link to be added to the Recent list, allowing the user to pin them. SHAddToRecentDocs(SHARD_LINK, pShellLink); Exit: PropVariantClear(&propVariant); SAFE_RELEASE(pPropertyStore); SAFE_RELEASE(pShellLink); return hr; }
bool CreateLinkInner(wchar_t *filename, wchar_t *target, wchar_t *workdir, wchar_t *args, wchar_t *comment, wchar_t *icon, UINT icon_index) { HRESULT r; bool ret; IShellLinkW* pShellLink; IPersistFile* pPersistFile; if (OS_IS_WINDOWS_9X(GetOsInfo()->OsType)) { char *a1, *a2, *a3, *a4, *a5, *a6; a1 = CopyUniToStr(filename); a2 = CopyUniToStr(target); a3 = CopyUniToStr(workdir); a4 = CopyUniToStr(args); a5 = CopyUniToStr(icon); a6 = CopyUniToStr(comment); ret = CreateLinkInnerA(a1, a2, a3, a4, a6, a5, icon_index); Free(a1); Free(a2); Free(a3); Free(a4); Free(a5); Free(a6); return ret; } r = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void **)&pShellLink); if (FAILED(r)) { return false; } r = pShellLink->QueryInterface(IID_IPersistFile,(void **)&pPersistFile); if (FAILED(r)) { pShellLink->Release(); return false; } r = pShellLink->SetPath(target); if (FAILED(r)) { pShellLink->Release(); pPersistFile->Release(); return false; } if (workdir != NULL) { r = pShellLink->SetWorkingDirectory(workdir); if (FAILED(r)) { pShellLink->Release(); pPersistFile->Release(); return false; } } if (comment != NULL) { r = pShellLink->SetDescription(comment); if (FAILED(r)) { pShellLink->Release(); pPersistFile->Release(); return false; } } if (args != NULL) { r = pShellLink->SetArguments(args); if (FAILED(r)) { pShellLink->Release(); pPersistFile->Release(); return false; } } if (icon != NULL) { r = pShellLink->SetIconLocation(icon, icon_index); if (FAILED(r)) { pShellLink->Release(); pPersistFile->Release(); return false; } } r = pPersistFile->Save(filename, true); if (FAILED(r)) { pShellLink->Release(); pPersistFile->Release(); return false; } pShellLink->Release(); pPersistFile->Release(); return true; }
// (static) Creates a ShellLink that encapsulate a shortcut to local apps. nsresult JumpListShortcut::GetShellLink(nsCOMPtr<nsIJumpListItem>& item, nsRefPtr<IShellLinkW>& aShellLink, nsCOMPtr<nsIThread> &aIOThread) { HRESULT hr; IShellLinkW* psl; nsresult rv; // Shell links: // http://msdn.microsoft.com/en-us/library/bb776891(VS.85).aspx // http://msdn.microsoft.com/en-us/library/bb774950(VS.85).aspx int16_t type; if (NS_FAILED(item->GetType(&type))) return NS_ERROR_INVALID_ARG; if (type != nsIJumpListItem::JUMPLIST_ITEM_SHORTCUT) return NS_ERROR_INVALID_ARG; nsCOMPtr<nsIJumpListShortcut> shortcut = do_QueryInterface(item, &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsILocalHandlerApp> handlerApp; rv = shortcut->GetApp(getter_AddRefs(handlerApp)); NS_ENSURE_SUCCESS(rv, rv); // Create a IShellLink hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl); if (FAILED(hr)) return NS_ERROR_UNEXPECTED; // Retrieve the app path, title, description and optional command line args. nsAutoString appPath, appTitle, appDescription, appArgs; int32_t appIconIndex = 0; // Path nsCOMPtr<nsIFile> executable; handlerApp->GetExecutable(getter_AddRefs(executable)); rv = executable->GetPath(appPath); NS_ENSURE_SUCCESS(rv, rv); // Command line parameters uint32_t count = 0; handlerApp->GetParameterCount(&count); for (uint32_t idx = 0; idx < count; idx++) { if (idx > 0) appArgs.Append(NS_LITERAL_STRING(" ")); nsAutoString param; rv = handlerApp->GetParameter(idx, param); if (NS_FAILED(rv)) return rv; appArgs.Append(param); } handlerApp->GetName(appTitle); handlerApp->GetDetailedDescription(appDescription); bool useUriIcon = false; // if we want to use the URI icon bool usedUriIcon = false; // if we did use the URI icon shortcut->GetIconIndex(&appIconIndex); nsCOMPtr<nsIURI> iconUri; rv = shortcut->GetFaviconPageUri(getter_AddRefs(iconUri)); if (NS_SUCCEEDED(rv) && iconUri) { useUriIcon = true; } // Store the title of the app if (appTitle.Length() > 0) { IPropertyStore* pPropStore = nullptr; hr = psl->QueryInterface(IID_IPropertyStore, (LPVOID*)&pPropStore); if (FAILED(hr)) return NS_ERROR_UNEXPECTED; PROPVARIANT pv; InitPropVariantFromString(appTitle.get(), &pv); pPropStore->SetValue(PKEY_Title, pv); pPropStore->Commit(); pPropStore->Release(); PropVariantClear(&pv); } // Store the rest of the params psl->SetPath(appPath.get()); psl->SetDescription(appDescription.get()); psl->SetArguments(appArgs.get()); if (useUriIcon) { nsString icoFilePath; rv = mozilla::widget::FaviconHelper::ObtainCachedIconFile(iconUri, icoFilePath, aIOThread, false); if (NS_SUCCEEDED(rv)) { // Always use the first icon in the ICO file // our encoded icon only has 1 resource psl->SetIconLocation(icoFilePath.get(), 0); usedUriIcon = true; } } // We didn't use an ICO via URI so fall back to the app icon if (!usedUriIcon) { psl->SetIconLocation(appPath.get(), appIconIndex); } aShellLink = dont_AddRef(psl); return NS_OK; }
BOOL MetaLauncher::createMenuItem(ULONG id, const char *path, size_t pathlen) { vnclog.Print(1, _T("%s: id=0x%X\n"), __FUNCTION__, id); wchar_t *p; // setup link path : m_baseMenuFolder + path (+ @desktopname) + ".lnk" size_t linkPathLen = wcslen(m_baseMenuFolder) + pathlen + wcslen(m_clientconn->m_desktopNameW) + 6; wchar_t *linkPath = new wchar_t[linkPathLen]; wcscpy(linkPath, m_baseMenuFolder); // append path with converting UTF-8 to UCS-2LE int pos = wcslen(linkPath); int wlen = MultiByteToWideChar(CP_UTF8, 0, path, (int)pathlen, &linkPath[pos], linkPathLen - pos); if (wlen <= 0) { vnclog.Print(0, _T("MultiByteToWideChar failed. (error %d)\n"), GetLastError()); delete[] linkPath; return FALSE; } linkPath[pos + wlen] = L'\0'; // convert '/' to '\\' while ((p = wcschr(linkPath, L'/')) != NULL) *p = L'\\'; // setup description text wchar_t *appName = wcsrchr(linkPath, '\\'); if (appName != NULL) appName++; // remove first '\\' else appName = linkPath; wchar_t *description = new wchar_t[wcslen(appName) + 1 + wcslen(m_clientconn->m_desktopNameW) + 1]; wcscpy(description, appName); wcscat(description, L"@"); wcscat(description, m_clientconn->m_desktopNameW); // add remote desktop name to linkpath if menu directory is not separated // XXX: maybe another option is needed if (m_clientconn->m_opts.m_menuLoc != MENULOC_SEPARATE) { wcscat(linkPath, L"@"); wcscat(linkPath, m_clientconn->m_desktopNameW); } wcscat(linkPath, L".lnk"); // add extension // check if linkPath already exists struct _stat st; if (_wstat(linkPath, &st) == 0) { vnclog.Print(0, _T("Failed to create identical link path (id=0x%X).\n"), id); delete[] description; delete[] linkPath; return FALSE; } // create sub directories createMenuDirs(linkPath); // remember link path if (m_fpMenuList) { fputws(linkPath, m_fpMenuList); fputws(L"\n", m_fpMenuList); } // setup target command arguments wchar_t targetArgs[30]; _snwprintf(targetArgs, 30, L"-launch %08X:%08X", m_clientconn->m_hwnd1, id); // setup icon path wchar_t *iconPath = createIconPath(id); // create shortcut HRESULT hr; IShellLinkW *pShellLink; IPersistFile *pPersistFile; CoInitialize(NULL); hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void**)&pShellLink); if (hr == S_OK) hr = pShellLink->SetPath(m_programName); if (hr == S_OK) hr = pShellLink->SetArguments(targetArgs); if (hr == S_OK) hr = pShellLink->SetIconLocation(iconPath, 0); if (hr == S_OK) hr = pShellLink->SetDescription(description); if (hr == S_OK) hr = pShellLink->QueryInterface(IID_IPersistFile, (void **)&pPersistFile); if (hr == S_OK) hr = pPersistFile->Save(linkPath, TRUE); // clean up pPersistFile->Release(); pShellLink->Release(); CoUninitialize(); delete[] iconPath; delete[] description; delete[] linkPath; return (hr == S_OK); }
HRESULT ShellFunctions::CreateShortcut(LPCWSTR pszShortcutFile,LPCWSTR pszLink,LPCWSTR pszDesc,LPCWSTR pszParams) { HRESULT hres; if (IsUnicodeSystem()) { IShellLinkW* psl; hres=CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLinkW,(void**)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; hres=psl->QueryInterface(IID_IPersistFile,(void**)&ppf); if (SUCCEEDED(hres)) { hres=psl->SetPath(pszLink); if (SUCCEEDED(hres)) { int nIndex=LastCharIndex(pszLink,L'\\'); if (nIndex>=0) { WCHAR szWDir[MAX_PATH]; MemCopyW(szWDir,pszLink,nIndex); szWDir[nIndex]='\0'; psl->SetWorkingDirectory(szWDir); } if (pszDesc!=NULL) psl->SetDescription(pszDesc); if (pszParams!=NULL) psl->SetArguments(pszParams); hres=ppf->Save(pszShortcutFile,TRUE); } ppf->Release(); } psl->Release(); } } else { IShellLink* psl; hres=CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(void**)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; hres=psl->QueryInterface(IID_IPersistFile,(void**)&ppf); if (SUCCEEDED(hres)) { hres=psl->SetPath(W2A(pszLink)); if (SUCCEEDED(hres)) { LONG_PTR nIndex=LastCharIndex(pszLink,L'\\'); if (nIndex>=0) { char szWDir[MAX_PATH]; WideCharToMultiByte(CP_ACP,0,pszLink,(int)nIndex,szWDir,MAX_PATH,0,0); szWDir[nIndex]='\0'; psl->SetWorkingDirectory(szWDir); } if (pszDesc!=NULL) psl->SetDescription(W2A(pszDesc)); if (pszParams!=NULL) psl->SetArguments(W2A(pszParams)); hres=ppf->Save(pszShortcutFile,TRUE); } ppf->Release(); } psl->Release(); } } return hres; }
// (static) Creates a ShellLink that encapsulate a shortcut to local apps. nsresult JumpListShortcut::GetShellLink(nsCOMPtr<nsIJumpListItem>& item, nsRefPtr<IShellLinkW>& aShellLink) { HRESULT hr; IShellLinkW* psl; nsresult rv; // Shell links: // http://msdn.microsoft.com/en-us/library/bb776891(VS.85).aspx // http://msdn.microsoft.com/en-us/library/bb774950(VS.85).aspx PRInt16 type; if (NS_FAILED(item->GetType(&type))) return NS_ERROR_INVALID_ARG; if (type != nsIJumpListItem::JUMPLIST_ITEM_SHORTCUT) return NS_ERROR_INVALID_ARG; nsCOMPtr<nsIJumpListShortcut> shortcut = do_QueryInterface(item, &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsILocalHandlerApp> handlerApp; rv = shortcut->GetApp(getter_AddRefs(handlerApp)); NS_ENSURE_SUCCESS(rv, rv); // Create a IShellLink hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl); if (FAILED(hr)) return NS_ERROR_UNEXPECTED; // Retrieve the app path, title, description and optional command line args. nsAutoString appPath, appTitle, appDescription, appArgs; PRInt32 appIconIndex = 0; // Path nsCOMPtr<nsIFile> executable; handlerApp->GetExecutable(getter_AddRefs(executable)); nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(executable, &rv); NS_ENSURE_SUCCESS(rv, rv); rv = localFile->GetPath(appPath); NS_ENSURE_SUCCESS(rv, rv); // Command line parameters PRUint32 count = 0; handlerApp->GetParameterCount(&count); for (PRUint32 idx = 0; idx < count; idx++) { if (idx > 0) appArgs.Append(NS_LITERAL_STRING(" ")); nsAutoString param; rv = handlerApp->GetParameter(idx, param); if (NS_FAILED(rv)) return rv; appArgs.Append(param); } handlerApp->GetName(appTitle); handlerApp->GetDetailedDescription(appDescription); shortcut->GetIconIndex(&appIconIndex); // Store the title of the app if (appTitle.Length() > 0) { IPropertyStore* pPropStore = nsnull; hr = psl->QueryInterface(IID_IPropertyStore, (LPVOID*)&pPropStore); if (FAILED(hr)) return NS_ERROR_UNEXPECTED; PROPVARIANT pv; InitPropVariantFromString(appTitle.get(), &pv); pPropStore->SetValue(PKEY_Title, pv); pPropStore->Commit(); pPropStore->Release(); PropVariantClear(&pv); } // Store the rest of the params psl->SetPath(appPath.get()); psl->SetDescription(appDescription.get()); psl->SetArguments(appArgs.get()); psl->SetIconLocation(appPath.get(), appIconIndex); aShellLink = dont_AddRef(psl); return NS_OK; }