Archive: Uninstall icon in Start Menu isn't shown


Uninstall icon in Start Menu isn't shown
Hello,
After installing the application, the installer and uninstaller icons are properly shown in application folder in Start menu, but the uninstaller icon is missing from the main Start menu (see attachment)
What am I missing here?

It's 64-bit Windows, program is installed in Program Files (x86). But looks like it's not the same problem as discussed in http://forums.winamp.com/showthread.php?t=327806


Could you give us some code?

Stu


!define MUI_ICON myapp_install.ico
!define MUI_UNICON myapp_uninstall.ico

In install section:

CreateDirectory "$SMPROGRAMS\${APP_NAME}"
CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" "$INSTDIR\${APPFILE}"
CreateShortCut '$SMPROGRAMS\${APP_NAME}\${UNINSTALL_SHORTCUT}.lnk' "${UNINST_EXE}"


The problem appears only when installing in Program Files (x86) folder. When I install to another folder, select uninstaller icon and do "Pin to Start Menu", the uninstaller icon is ok. If I install to Program Files (x86), same actions lead to a default icon in start menu (as on the image attacted).


If I select the menu item with the default icon and choose "Properties->Change Icon" I see the path to file with icons looking like this:

C:\Program Files (x86)\App\Uninstall.exe

The icon is seen in icon view below in properties. But it still doesn't appear in menu.

If I change it to

%ProgramFiles% (x86)\App\Uninstall.exe

and save this setting, the uninstaller icon appears ok.


Could you upload this .lnk somewhere?


Here it is. I've renamed it to .lnkk for convenient uploading.
http://www.sendspace.com/file/7jl8qq
This .lnk is both in Programs/AppName/ and in main start menu (on attached image). In Programs/AppName/ the icon is ok.


That lnk does not contain a icon block so it should just use the icon of the target. Does clicking the shortcut with the broken icon actually work?

Flags: 0x99
ShItemIdList
HasRelativePath
HasWorkDir
Unicode
TargetFileAttributes: 0x0
TargetCreated: N/A
TargetLastAccess: N/A
TargetModified: N/A
TargetSize: 0
IconIndex: 0
ShowCmd: NORMAL
HotKey: 0x0

RelativePath: ..\..\..\..\..\..\Program Files (x86)\Yota\Play\Uninstall.exe
WorkDir: C:\Program Files (x86)\Yota\Play

ShItemIdList
------------
Length: 415
9D 01 14 00 1F 50 E0 4F D0 20 EA 3A 69 10 A2 D8 .....P.O...:i...
08 00 2B 30 30 9D 19 00 2F 43 3A 5C 00 00 00 00 ..+00.../C:\....
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 76 ...............v
00 31 00 00 00 00 00 00 00 00 00 10 00 50 72 6F .1...........Pro
67 72 61 6D 20 46 69 6C 65 73 20 28 78 38 36 29 gram.Files.(x86)
00 54 00 08 00 04 00 EF BE 00 00 00 00 00 00 00 .T..............
00 2A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .*..............
00 00 00 00 00 00 00 00 00 00 00 50 00 72 00 6F ...........P.r.o
00 67 00 72 00 61 00 6D 00 20 00 46 00 69 00 6C .g.r.a.m...F.i.l
00 65 00 73 00 20 00 28 00 78 00 38 00 36 00 29 .e.s...(.x.8.6.)
00 00 00 22 00 4A 00 31 00 00 00 00 00 00 00 00 ...".J.1........
00 10 00 59 6F 74 61 00 00 36 00 08 00 04 00 EF ...Yota..6......
BE 00 00 00 00 00 00 00 00 2A 00 00 00 00 00 00 .........*......
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 59 00 6F 00 74 00 61 00 00 00 14 00 4A ...Y.o.t.a.....J
00 31 00 00 00 00 00 00 00 00 00 10 00 50 6C 61 .1...........Pla
79 00 00 36 00 08 00 04 00 EF BE 00 00 00 00 00 y..6............
00 00 00 2A 00 00 00 00 00 00 00 00 00 00 00 00 ...*............
00 00 00 00 00 00 00 00 00 00 00 00 00 50 00 6C .............P.l
00 61 00 79 00 00 00 14 00 64 00 32 00 00 00 00 .a.y.....d.2....
00 00 00 00 00 00 00 55 6E 69 6E 73 74 61 6C 6C .......Uninstall
2E 65 78 65 00 48 00 08 00 04 00 EF BE 00 00 00 .exe.H..........
00 00 00 00 00 2A 00 00 00 00 00 00 00 00 00 00 .....*..........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 ...............U
00 6E 00 69 00 6E 00 73 00 74 00 61 00 6C 00 6C .n.i.n.s.t.a.l.l
00 2E 00 65 00 78 00 65 00 00 00 1C 00 00 00 ...e.x.e.......

SpecialFolderDataBlock
----------------------
SpecialFolderId: 0x2A
PIDL Offset: 163

KnownFolderDataBlock
--------------------
KnownFolder: {7C5A40EF-A0FB-4BFC-874A-C0F2e0b9fa8e}
PIDL Offset: 163
What I wanted to check was SpecialFolderId and KnownFolder, if they specify the non x86 version of the shell constant it can fail on x64, but then launching the thing should also fail (Not sure if the icon lookup uses the same algorithm as the execution) 0x2A should be the x86 specific constant.

Could it be a icon cache problem? Did you try on another machine or another user?

Yes, the problem persists if another user on another machine installs the app.
Clicking on this shortcut actually works.


How do you explore the .lnk file?


Originally posted by juliarg
How do you explore the .lnk file?
I used my own private tool, sorry.

The file format is documented @ http://msdn.microsoft.com/en-us/libr...PROT.10).aspx#[MS-SHLLINK]: Shell Link (.LNK) Binary File Format

Could you then please have a look at this .lnk file?

http://www.sendspace.com/file/nqi7am

It's after I changed the "search for icons in the following file" property from

C:\Program Files (x86)\App\Uninstall.exe

to

%ProgramFiles% (x86)\App\Uninstall.exe

and then, the icon is there.

I wonder how the .lnk has changed, maybe it could give a clue.


...
RelativePath: ..\..\..\..\..\..\Program Files (x86)\Yota\Play\Uninstall.exe
WorkDir: C:\Program Files (x86)\Yota\Play
IconPath: %ProgramFiles% (x86)\Yota\Play\Uninstall.exe

ShItemIdList
...
But "%ProgramFiles% (x86)" is not really a valid thing, you are just getting lucky.

Is there a way to put this IconPath in the .lnk via NSIS? I'm puzzled.


Originally posted by juliarg
Is there a way to put this IconPath in the .lnk via NSIS? I'm puzzled.
You can set a specific icon in the CreateShortcut call (But it should NOT be required when it is the same as the target)

I have been playing around with some code, but I don't know how to get the icon path used when a .lnk does not specify a specific icon (I could probably fall back to the path from IShellLink::GetPath but I was hoping there was some shell function that would provide it for me)


I ran your code for the problem .lnk.

GetPath:0=C:\Program Files (x86)\Yota\Play\Uninstall.exe
GetIconLocation:0=,0
IShellLink HR=0
GetIconLocation:0=*|idx=7 flags=12
Extract:0=HICON=508627137
SHGetFileInfo=1|,0
SHMapPIDLToSystemImageListIndex=7


I tried the following:
CreateShortCut "$SMPROGRAMS\${APP_NAME}\${UNINSTALL_SHORTCUT}.lnk" "${UNINST_EXE}" "" "${UNINST_EXE}"

After this, the icon remained default and on attempt to look at "Look for icons in this file" property I got ""Windows cannot find the file %ProgramFiles%\Yota\Play\uninstall.exe"

I applied the workaround from this topic http://forums.winamp.com/showthread.php?t=327806 and the message stopped appearing, "Look for icons in this file" path is correct. But the icon remains default.


Originally posted by juliarg
I ran your code for the problem .lnk.
Did the application icon change to the correct icon on the instfiles page?

Problem is not with the app icon, but with the uninstaller icon. On all the uninstaller pages, the icon is ok. It does not show only in the Start Menu (see attachment).
I am inclined to think that this is a Windows icon cache issue, because after I install and then update the app, the icon is ok.

I do this call for refreshing icons.
System::Call 'Shell32::SHChangeNotify(i 0x8000000, i 0, i 0, i 0)'

There is no specific code in installer to add an icon to the main Start menu (in attachment). Maybe this happens when installer is deinitialized, which is after the call to SHChangeNotify


I was actually talking about the little sample code I posted, it tries to set the icon from the .lnk


If I point it to the uninstaller .lnk, it sets the default icon to the instfiles page. I also tried pointing it to the application .lnk, it works - the application icon appears on the instfiles page.


Looking at the link dump again I see that TargetFileAttributes and TargetSize are both 0 in my dump (I did not have the target file on my system). Are you creating the shortcut before the uninstaller has been written? The shortcut target should exist when you create the shortcut...


:) Yes, you're right. I write the uninstaller in .onInstSuccess using Advanced Uninstall Log. The shortcuts are created in the install section.

I found out that if I do this

System::Call 'Shell32::SHChangeNotify(i 0x8000000, i 0, i 0, i 0)'

not at the end of install section, but on .onGuiEnd,

the icon is ok. Everything looks pretty simple now - the icon cache was refreshed when the uninstaller still was not there.


Don't use that in .onGUIEnd because it will get called when people cancel your install. You don't need to use .onInstSuccess either; just add an unnamed Section after all your sections and put any final unconditionally executed code in there.

Stu


But, in the documentation to Advanced Uninstall Log, they recommend to call the macro which creates the uninstaller in .onInstSuccess. That's how it's done now in my installer. And I need to refresh the cache after the uninstaller is created.


@Anders
wait til MSG finds out about this post, he'll teach you to attach large chunks of code :p


At least Anders has the sense not to use the broken code tag >_>


(btw @admins: please get to fixing that already...)


actually it was me that converted it to a quote block and i'll go through the posts in a few minutes and convert things to attachments as applicable.

as for fixing the code block issue, it is logged but it's massively down at the bottom of the list of things to do (though why VB3.x does it different is beyond me).

-daz


In that case, can't you just workaround it to let vB interpret all code tags as php or quote instead? That'd be infinitely better than the mess that currently is the code tag.


@MSG
just kidding


MSG: that still involves someone doing something though why going from VB2.x to VB3.x broke it i just don't know. there are things listed and i've mentioned it many times but the forums are low on the list of everything else that needs to be allocated resources. same as fixing some of the attachment upload issues, etc etc.

-daz


Originally posted by MSG
At least Anders has the sense not to use the broken code tag >_>
The PHP formating eats the \ so I had to go with CODE