tags:

views:

299

answers:

3

How can I change the target of a desktop icon (but not the displayed icon) with a "programming language" (vbscript or anything else) ?

for example:

C:\Program Files\Mozilla Firefox\firefox.exe

(with firefox-logo-icon-picture)

to

E:\start_firefox.bat

(with the same display icon, and not the "bat" icon)

A: 

Since the icon displayed by Windows (I'm assuming you're running Windows since you mention \Program Files\ and a .bat file) is dependent upon the file extension (BAT in this case) and that file extension determines what icon is displayed, this can't be done without reassociating a particular application with that particular extension (which I don't recommend).

The next best thing I can think is to replace the link with an executable that uses the icon of the application you're trying to "spoof."

Michael Todd
A: 
// Assume you have the path to the shortcut in pszFilename.

CComPtr<IPersistFile> persist_file;
HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IPersistFile, (LPVOID*)&persist_file); 
if (SUCCEEDED(hr)) { 
    hr = persist_file->Load(pszFilename, 0);
}

CComPtr<IShellLink> shell_link;
if (SUCCEEDED(hr)) {
    hr = persist_file->QueryInterface(IID_IShellLink, (void**)&shell_link);
}

// Assume the new target you want to set is in pszNewTargetPath.

if (SUCCEEDED(hr)) {
    hr = shell_link->SetPath(pszNewTargetPath); 
}

if (SUCCEEDED(hr)) {
    hr = persist_file->Save(pszFilename, true);
}
jeffamaphone
So, how does this work? I see that you're loading the target file in the IID_IShellLink context, then setting a new path, but how does this retain the old icon yet set a new target?
Michael Todd
Well, I'm assuming that if you don't mess with IShellLink::SetIconPath or whatever, then it won't change it. It's possible SetPath has side effects... in which case you'll just need to call SetIconPath afterward and point it to your icon of choice. Though if the target app is uninstalled your icon will go away.
jeffamaphone
A: 

Here's a VBScript sample:

' ChangeDesktopLink.vbs

' Uncomment the proper constant:
' Const DESKTOP_DIR = &H19   ' Common desktop folder, e.g. C:\Documents and Settings\All Users\Desktop
Const DESKTOP_DIR  = &H10    ' User's desktop folder, e.g. C:\Documents and Settings\<username>\Desktop

Set oShell = CreateObject("Shell.Application")
With oShell.Namespace(DESKTOP_DIR).ParseName("Firefox.lnk").GetLink
  .Path = "E:\start_firefox.bat"
  .Save
End With
Helen
And changing the path will still allow it to maintain the icon from the previous path? Amazing.
Michael Todd
Seems reasonable that the two are controllable independently. Functions, in general, shouldn't have side effects.
jeffamaphone