// (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;
}
Beispiel #2
0
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));
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
	}
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #10
0
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();
}
Beispiel #12
0
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();
}
Beispiel #13
0
//---------------------------------------------------------------------------
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;
}