Click to See Complete Forum and Search --> : IShellLink::GetIconLocation() fails


wey97
January 27th, 2004, 06:31 PM
You need a text file named test.txt on your c:\ drive and a shortcut to the text file named test on c:\

(right click test.txt and choose Create Shortcut and rename the shortcut test)

The call to GetPath() gets the correct path from the shortcut to the actual file but GetIconLocation() is empty.

#include <windows.h>
#include <shobjidl.h>
#include <shlguid.h>

#include <iostream>
using namespace std;

HRESULT GetIconPath(string link)
{
HRESULT hRes;
IShellLink* pISL;
IPersistFile* pIPF;
WCHAR wszText[MAX_PATH];
TCHAR szText[MAX_PATH];
INT nIndex = -1;
INT *pnIndex = &nIndex;

hRes = CoInitialize(NULL);

if(hRes == S_OK)
{
hRes = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (LPVOID*)&pISL);

if(hRes == S_OK)
{
hRes = pISL->QueryInterface(IID_IPersistFile, (LPVOID*)&pIPF);

if(hRes == S_OK)
{
MultiByteToWideChar(0, 0, link.c_str(), -1, wszText, MAX_PATH);
pIPF->Load(wszText, STGM_READ);
hRes = pISL->GetPath(szText, MAX_PATH, NULL, SLGP_UNCPRIORITY);

if(hRes == S_OK)
{
cout << "Path = " << szText << endl;
}

hRes = pISL->GetIconLocation(szText, MAX_PATH, pnIndex);

if(hRes == S_OK)
{
cout << "Icon Loc = " << szText << " Index = " << nIndex << endl;
}
}
pIPF->Release();
}
pISL->Release();
}
CoUninitialize();
return hRes;
}

int main()
{

GetIconPath("c:\\test.lnk");

system("pause");
}


Any ideas?

hankdane
January 27th, 2004, 07:43 PM
Originally posted by wey97
Any ideas?

Yes. The shortcut does not have an icon associated with it. I'm not sure what type of return you expected from GetIconLocation() in that situation.

You may want to look at IShellIcon::GetIconOf();

joscollin
January 27th, 2004, 10:45 PM
You can use SHGetFileInfo (or ExtractAssociatedIcon()) for getting icon information from a file.

Instead of system("pause") you can use Semaphores for the main thread to wait.

wey97
January 28th, 2004, 10:38 AM
Originally posted by hankdane
Yes. The shortcut does not have an icon associated with it. I'm not sure what type of return you expected from GetIconLocation() in that situation.

You may want to look at IShellIcon::GetIconOf();
from MSDN
The IShellIcon interface is used to obtain an icon index for an IShellFolder object.

GetIconOf Retrieves an icon for an object inside a specific folder.

I think IShellIcon::GetIconOf() is only useful for getting folder icons.
Originally posted by joscollin
You can use SHGetFileInfo (or ExtractAssociatedIcon()) for getting icon information from a file.

Instead of system("pause") you can use Semaphores for the main thread to wait.
ExtractAssociatedIcon() is what I needed.

I just use system("pause") so I can see the program output before the window closes.
If not, the window closes automatically on .NET without the 'Press any key to continue' in VC++ 6.0.

joscollin
January 29th, 2004, 01:29 AM
Originally posted by wey97
I think IShellIcon::GetIconOf() is only useful for getting folder icons.

ExtractAssociatedIcon() is what I needed.

I just use system("pause") so I can see the program output before the window closes.
If not, the window closes automatically on .NET without the 'Press any key to continue' in VC++ 6.0.

The window closes because your main thread creating the it closes. You can wait the main thread instead of executing a system command. Also release the thread when you give the specific input for closing.

wey97
January 29th, 2004, 08:27 AM
Originally posted by joscollin
The window closes because your main thread creating the it closes. You can wait the main thread instead of executing a system command. Also release the thread when you give the specific input for closing.
So you're suggesting that I add calls to:

CreateSemaphore(...)
WaitForSingleObject(...)
Get the user input...
ReleaseSemaphore(...)
CloseHandle(...)

Why would I want to put that much extra code into an app anyway?
I mean really, system("pause") does essentially what the environment from VC++ 6.0 did anyway.

I don't see any advantages to doing what you say.

joscollin
January 29th, 2004, 12:32 PM
Originally posted by wey97
So you're suggesting that I add calls to:

CreateSemaphore(...)
WaitForSingleObject(...)
Get the user input...
ReleaseSemaphore(...)
CloseHandle(...)

Why would I want to put that much extra code into an app anyway?
I mean really, system("pause") does essentially what the environment from VC++ 6.0 did anyway.

I don't see any advantages to doing what you say.

Yes you are correct.

In my project I'm using semaphores.
I'm creating somany threads from the main and I'm very much comfortable using semaphores because I need to release the main thread from more than one place in the code.

I think in your case your method is good.