// (static) Creates a ShellLink that encapsulate a separator. nsresult JumpListSeparator::GetSeparator(nsRefPtr<IShellLinkW>& aShellLink) { HRESULT hr; IShellLinkW* psl; // Create a IShellLink. hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl); if (FAILED(hr)) return NS_ERROR_UNEXPECTED; IPropertyStore* pPropStore = nullptr; hr = psl->QueryInterface(IID_IPropertyStore, (LPVOID*)&pPropStore); if (FAILED(hr)) return NS_ERROR_UNEXPECTED; PROPVARIANT pv; InitPropVariantFromBoolean(TRUE, &pv); pPropStore->SetValue(PKEY_AppUserModel_IsDestListSeparator, pv); pPropStore->Commit(); pPropStore->Release(); PropVariantClear(&pv); aShellLink = dont_AddRef(psl); return NS_OK; }
HRESULT _CreateSeparatorLink(IShellLink **ppsl) { IPropertyStore *pps; HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pps)); if (SUCCEEDED(hr)) { PROPVARIANT propvar; hr = InitPropVariantFromBoolean(TRUE, &propvar); if (SUCCEEDED(hr)) { hr = pps->SetValue(PKEY_AppUserModel_IsDestListSeparator, propvar); if (SUCCEEDED(hr)) { hr = pps->Commit(); if (SUCCEEDED(hr)) { hr = pps->QueryInterface(IID_PPV_ARGS(ppsl)); } } PropVariantClear(&propvar); } pps->Release(); } return hr; }
void JumpListsManager::addTask(ActionInfo *info) { if (!m_destList) return; WinApi::IShellLinkW *task; HRESULT res = CoCreateInstance(WinApi::CLSID_ShellLink, 0, CLSCTX_INPROC_SERVER, WinApi::IID_IShellLinkW, (void**)&task); if (FAILED(res)) return; task->SetDescription(info->description); task->SetPath(L"rundll32.exe"); task->SetArguments(makeArgs(info).c_str()); if (info->iconPath) task->SetIconLocation(info->iconPath, 0); IPropertyStore *title; PROPVARIANT titlepv; res = task->QueryInterface(IID_IPropertyStore, (void**)&title); if (FAILED(res)) { task->Release(); return; } InitPropVariantFromString(info->name, &titlepv); title->SetValue(PKEY_Title, titlepv); title->Commit(); WinApi::PropVariantClear(&titlepv); res = m_destListContent->AddObject(task); title->Release(); task->Release(); m_actionInfoMap.insert(std::make_pair(info->id, info)); }
HRESULT CTaskbar7::CreateShellLink(Destination destination, IShellLink **ppShellLink) { USES_CONVERSION; IShellLink *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(CW2A(destination.path.c_str())); EXIT_ON_ERROR(hr); // Arguments hr = pShellLink->SetArguments(CW2A(destination.arguments.c_str())); EXIT_ON_ERROR(hr); // Working Directory if (!destination.workingFolder.empty()) { hr = pShellLink->SetWorkingDirectory(CW2A(destination.workingFolder.c_str())); EXIT_ON_ERROR(hr); } // Icon Location if (!destination.icon.empty()) { hr = pShellLink->SetIconLocation(CW2A(destination.icon.c_str()), destination.iconIndex); EXIT_ON_ERROR(hr); } hr = pShellLink->QueryInterface(IID_PPV_ARGS(&pPropertyStore)); EXIT_ON_ERROR(hr); // Name hr = InitPropVariantFromString(destination.name.c_str(), &propVariant); EXIT_ON_ERROR(hr); hr = pPropertyStore->SetValue(PKEY_Title, propVariant); EXIT_ON_ERROR(hr); hr = pPropertyStore->Commit(); EXIT_ON_ERROR(hr); hr = pShellLink->QueryInterface(IID_PPV_ARGS(ppShellLink)); Exit: PropVariantClear(&propVariant); SAFE_RELEASE(pPropertyStore); SAFE_RELEASE(pShellLink); return hr; }
HRESULT SetPropertyValue(PCWSTR pszFilename, PCWSTR pszCanonicalName, PCWSTR pszValue) { // Convert the Canonical name of the property to PROPERTYKEY PROPERTYKEY key; HRESULT hr = PSGetPropertyKeyFromName(pszCanonicalName, &key); if (SUCCEEDED(hr)) { IPropertyStore* pps = NULL; // Call the helper to get the property store for the // initialized item hr = GetPropertyStore(pszFilename, GPS_READWRITE, &pps); if (SUCCEEDED(hr)) { PROPVARIANT propvarValue = {0}; hr = InitPropVariantFromString(pszValue, &propvarValue); if (SUCCEEDED(hr)) { hr = PSCoerceToCanonicalValue(key, &propvarValue); if (SUCCEEDED(hr)) { // Set the value to the property store of the item. hr = pps->SetValue(key, propvarValue); if (SUCCEEDED(hr)) { // Commit does the actual writing back to the file stream. hr = pps->Commit(); if (SUCCEEDED(hr)) { wprintf(L"Property %s value %s written successfully \n", pszCanonicalName, pszValue); } else { wprintf(L"Error %x: Commit to the propertystore failed.\n", hr); } } else { wprintf(L"Error %x: Set value to the propertystore failed.\n", hr); } } PropVariantClear(&propvarValue); } pps->Release(); } else { wprintf(L"Error %x: getting the propertystore for the item.\n", hr); } } else { wprintf(L"Invalid property specified: %s\n", pszCanonicalName); } return hr; }
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 _CreateShellLink(PCSTR pszArguments, PCWSTR pszTitle, LPCSTR szDescription, IShellLink **ppsl) { IShellLink *psl; HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&psl)); if (SUCCEEDED(hr)) { // Determine our executable's file path so the task will execute this application CHAR szAppPath[MAX_PATH]; if (GetModuleFileName(NULL, szAppPath, ARRAYSIZE(szAppPath))) { hr = psl->SetPath(szAppPath); if (SUCCEEDED(hr)) { hr = psl->SetArguments(pszArguments); if (SUCCEEDED(hr)) { hr = psl->SetDescription( szDescription ); if (SUCCEEDED(hr)) { // The title property is required on Jump List items provided as an IShellLink // instance. This value is used as the display name in the Jump List. IPropertyStore *pps; hr = psl->QueryInterface(IID_PPV_ARGS(&pps)); if (SUCCEEDED(hr)) { PROPVARIANT propvar; hr = InitPropVariantFromString(pszTitle, &propvar); if (SUCCEEDED(hr)) { hr = pps->SetValue(PKEY_Title, propvar); if (SUCCEEDED(hr)) { hr = pps->Commit(); if (SUCCEEDED(hr)) { hr = psl->QueryInterface(IID_PPV_ARGS(ppsl)); } } PropVariantClear(&propvar); } pps->Release(); } } } } } else { hr = HRESULT_FROM_WIN32(GetLastError()); } psl->Release(); } return hr; }
BOOL install_util::CreateLnkPath(std::wstring wsSourceFilePath, std::wstring wsDestLnkPath, std::wstring wsArgument, std::wstring wsAppId) { IShellLink *pisl = NULL; HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pisl); if (FAILED(hr)) { return FALSE; } pisl->SetPath(wsSourceFilePath.c_str()); pisl->SetArguments(wsArgument.c_str()); int nStart = wsSourceFilePath.find_last_of(_T("/\\")); pisl->SetWorkingDirectory(wsSourceFilePath.substr(0,nStart).c_str()); IPersistFile *plPF = NULL; hr = pisl->QueryInterface(IID_IPersistFile, (void**)&plPF); bool shortcut_existed = false; if (SUCCEEDED(hr)) { if (PathExists(wsDestLnkPath)) { shortcut_existed = true; install_util::DeleteFile(wsDestLnkPath.c_str()); } if (Win7OrLater() && !wsAppId.empty() && wsAppId.length() < 64) { IPropertyStore *piPS = NULL; if (SUCCEEDED(pisl->QueryInterface(IID_IPropertyStore, (void**)&piPS))) { PROPVARIANT property_value; if (SUCCEEDED(InitPropVariantFromString(wsAppId.c_str(), &property_value))) { if (piPS->SetValue(PKEY_AppUserModel_ID, property_value) == S_OK) piPS->Commit(); PropVariantClear(&property_value); } piPS->Release(); } } hr = plPF->Save(wsDestLnkPath.c_str(), TRUE); plPF->Release(); } pisl->Release(); SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); return SUCCEEDED(hr); }
// (static) ShellItems are used to encapsulate links to things. We currently only support URI links, // but more support could be added, such as local file and directory links. nsresult JumpListLink::GetShellItem(nsCOMPtr<nsIJumpListItem>& item, nsRefPtr<IShellItem2>& aShellItem) { IShellItem2 *psi = nullptr; nsresult rv; int16_t type; if (NS_FAILED(item->GetType(&type))) return NS_ERROR_INVALID_ARG; if (type != nsIJumpListItem::JUMPLIST_ITEM_LINK) return NS_ERROR_INVALID_ARG; nsCOMPtr<nsIJumpListLink> link = do_QueryInterface(item, &rv); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIURI> uri; rv = link->GetUri(getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv); nsAutoCString spec; rv = uri->GetSpec(spec); NS_ENSURE_SUCCESS(rv, rv); // Create the IShellItem if (FAILED(WinUtils::SHCreateItemFromParsingName( NS_ConvertASCIItoUTF16(spec).get(), NULL, IID_PPV_ARGS(&psi)))) { return NS_ERROR_INVALID_ARG; } // Set the title nsAutoString linkTitle; link->GetUriTitle(linkTitle); IPropertyStore* pPropStore = nullptr; HRESULT hres = psi->GetPropertyStore(GPS_DEFAULT, IID_IPropertyStore, (void**)&pPropStore); if (FAILED(hres)) return NS_ERROR_UNEXPECTED; PROPVARIANT pv; InitPropVariantFromString(linkTitle.get(), &pv); // May fail due to shell item access permissions. pPropStore->SetValue(PKEY_ItemName, pv); pPropStore->Commit(); pPropStore->Release(); PropVariantClear(&pv); aShellItem = dont_AddRef(psi); return NS_OK; }
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; }
void JumpListsManager::addSeparator() { WinApi::IShellLinkW *separator; IPropertyStore *propStore; PROPVARIANT pv; HRESULT res = CoCreateInstance(WinApi::CLSID_ShellLink, 0, CLSCTX_INPROC_SERVER, WinApi::IID_IShellLinkW, (void**)&separator); if (FAILED(res)) return; res = separator->QueryInterface(IID_IPropertyStore, (void**)&propStore); if (FAILED(res)) { separator->Release(); return; } InitPropVariantFromBoolean(TRUE, &pv); propStore->SetValue(PKEY_AppUserModel_IsDestListSeparator, pv); WinApi::PropVariantClear(&pv); propStore->Commit(); propStore->Release(); res = m_destListContent->AddObject(separator); separator->Release(); }
void TaskList::addToRecentList(QString name, QString user, QString host, int port) { if (! bIsWin7) return; HRESULT hr; IShellLink *link = NULL; IPropertyStore *ps = NULL; PROPVARIANT pt; hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, __uuidof(IShellLink), reinterpret_cast<void **>(&link)); if (!link || FAILED(hr)) return; QUrl url; url.setScheme(QLatin1String("mumble")); url.setUserName(user); url.setHost(host); url.setPort(port); #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) QUrlQuery query; query.addQueryItem(QLatin1String("title"), name); query.addQueryItem(QLatin1String("version"), QLatin1String("1.2.0")); url.setQuery(query); #else url.addQueryItem(QLatin1String("title"), name); url.addQueryItem(QLatin1String("version"), QLatin1String("1.2.0")); #endif QSettings settings(QLatin1String("HKEY_CLASSES_ROOT"), QSettings::NativeFormat); QString app = settings.value(QLatin1String("mumble/DefaultIcon/.")).toString(); if (app.isEmpty() || ! QFileInfo(app).exists()) app = QCoreApplication::applicationFilePath(); link->SetPath(app.toStdWString().c_str()); link->SetArguments(QString::fromLatin1(url.toEncoded()).toStdWString().c_str()); hr = link->QueryInterface(__uuidof(IPropertyStore), reinterpret_cast<void **>(&ps)); if (FAILED(hr)) { qFatal("TaskList: Failed to get property store"); goto cleanup; } InitPropVariantFromString(name.toStdWString().c_str(), &pt); hr = ps->SetValue(PKEY_Title, pt); PropVariantClear(&pt); if (FAILED(hr)) { qFatal("TaskList: Failed to set title"); goto cleanup; } hr = ps->Commit(); if (FAILED(hr)) { qFatal("TaskList: Failed commit"); goto cleanup; } SHAddToRecentDocs(SHARD_LINK, link); cleanup: if (ps) ps->Release(); if (link) link->Release(); }
//--------------------------------------------------------------------------- IShellLink * __fastcall CreateDesktopShortCut(const UnicodeString & Name, const UnicodeString &File, const UnicodeString & Params, const UnicodeString & Description, int SpecialFolder, int IconIndex, bool Return) { IShellLink* pLink = NULL; if (SpecialFolder < 0) { SpecialFolder = CSIDL_DESKTOPDIRECTORY; } try { if (SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &pLink))) { try { pLink->SetPath(File.c_str()); pLink->SetDescription(Description.c_str()); pLink->SetArguments(Params.c_str()); pLink->SetShowCmd(SW_SHOW); // Explicitly setting icon file, // without this icons are not shown at least in Windows 7 jumplist pLink->SetIconLocation(File.c_str(), IconIndex); IPersistFile* pPersistFile; if (!Return && SUCCEEDED(pLink->QueryInterface(IID_IPersistFile, (void **)&pPersistFile))) { try { LPMALLOC ShellMalloc; LPITEMIDLIST DesktopPidl; wchar_t DesktopDir[MAX_PATH]; OleCheck(SHGetMalloc(&ShellMalloc)); try { OleCheck(SHGetSpecialFolderLocation(NULL, SpecialFolder, &DesktopPidl)); OleCheck(SHGetPathFromIDList(DesktopPidl, DesktopDir)); } __finally { ShellMalloc->Free(DesktopPidl); ShellMalloc->Release(); } WideString strShortCutLocation(DesktopDir); // Name can contain even path (e.g. to create quick launch icon) strShortCutLocation += UnicodeString(L"\\") + Name + L".lnk"; OleCheck(pPersistFile->Save(strShortCutLocation.c_bstr(), TRUE)); } __finally { pPersistFile->Release(); } } // this is necessary for Windows 7 taskbar jump list links IPropertyStore * PropertyStore; if (SUCCEEDED(pLink->QueryInterface(IID_IPropertyStore, (void**)&PropertyStore))) { PROPVARIANT Prop; Prop.vt = VT_LPWSTR; Prop.pwszVal = Name.c_str(); PropertyStore->SetValue(PKEY_Title, Prop); PropertyStore->Commit(); PropertyStore->Release(); } } catch(...) { pLink->Release(); throw; } if (!Return) { pLink->Release(); pLink = NULL; } } } catch(Exception & E) { throw ExtException(&E, LoadStr(CREATE_SHORTCUT_ERROR)); } return pLink; }
// (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; }
// (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; }