- NSIS Discussion
- Local Machine Registry uninstaller
Archive: Local Machine Registry uninstaller
bnicer
7th January 2009 21:43 UTC
Local Machine Registry uninstaller
Hi again, Forum!
I miss this place.
=============
Maybe it's more of a philosophical question.
I've noticed in Vista the registry entries for installed software are (almost?) always under HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\.
Personally, I don't want users to have to invoke administrator privileges (for anything), which goes for the uninstallers too.
I'm forcing "RequestExecutionLevel user" and writing the uninstall registry entries into HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\.
But I wonder if my logic is flawed. Why does nobody else use HKCU (that I've noticed)? It was rare under XP. On Vista it seems (almost?) unheard of. Is there a reason?
Can anyone shed some light on this? Thx.
Anders
7th January 2009 21:50 UTC
no, no reason other than that most installers force you to be admin (programfiles access, broken installer or whatever the reason is)
so, if you are supporting per user installs, your are one of the (few) good guys *claps*
RDaneel
7th January 2009 22:25 UTC
Yes, well, I changed my NSIS installer a ways back to NOT require admin, and to perform ALL "visible" changes under HKCU and outside of "Program Files*"...
... and then I realized that NSIS's support of "delete/rename at next boot" wasn't working at all. I take it this is because MoveFilesEx uses HKLM?
Put differently, I really want to stay being one of the "good guys" - but I need my installer to work!
Again, none of MY reg key or filesystem ops needs admin, so if there is a trick here that allows the evil "...on next reboot" stuff to work with a NON-admin NSIS installer, I am all ears (or whatever the appropriate sensory apparatus would be). :)
Anders
7th January 2009 22:35 UTC
MoveFilesEx is HKLM only AFAIK, but you are not replacing system files in non admin installs, so you should be able to do your own filereplace trick in HKCU\...\Run (unless you have a component that is loaded in explorer.exe, then you might have to add some sort of checking to that COM object at load time so it does not load if a replace operation is going to happen (or a simpler way would be to unregister the COM object before restarting))
Not sure if any of this changed with Vista, one would think that MS add something for non admins since thats how they want people to run now
bnicer
7th January 2009 22:53 UTC
I have never needed a reboot, but I figure if something is still running that prevents installing right away, you could just halt the installer. Ask the user to fix it. It would be like:
"The selected folder is not empty. Please choose another destination."
Kind of.
RDaneel
7th January 2009 22:56 UTC
Indeed, my issue is because I have a Shell extension (or 2). :(
I am already doing the [re-]*registration* out of HKCU...RunOnce (based on some boilerplate from NSIS docs) using "rundll32.exe". Could you sketch out (or supply a pointer) handling deletes/renames out of HKCU...RunOnce too?
Of course, this doesn't solve the underlying problem of Microsoft's having never supplied a "guaranteed" way of updating a Shell extension without the archaic "reboot" (a major weakness of the whole component paradigm)... but it WOULD allow me to revert to non-admin installers! :)
Anders
7th January 2009 23:18 UTC
don't use RunOnce, IIRC, that is only for admin, use plain run and delete the entry after its done. The problem with shell exstensions is that they can stay loaded for a while, the only solution I could think of that does not include killing explorer.exe would be to inject a dll into explorer.exe and call CoFreeUnusedLibs or whatever that function is called
RDaneel
21st January 2009 22:16 UTC
I found no words suggesting that RunOnce has limited usage... and it actually does seem like the ideal thing here (cleaning up automatically etc). The documentation *is* interesting in that by default, RunOnce effectively removes the entry before actually executing it - if there is an error, too bad. BUT, the documentation goes on to cover how to request special handling (like NOT deleting the entry if an error occurs). :)
I have finished converting my installer from "install-32bit-on-32bit" to "install-32bit-on-32bit-AND-install-both-on-64bit", and it went pretty easily, once I got my head around requesting the register-64bit-DLL-on-reboot issue: the "trick" here was to make sure the RunOnce [in this case] went into the 64bit version of HKCU... that way the DllRegisterServer is invoked from a 64bit process. ;)
One last comment on how MoveFileEx is "screwed up" because it only works out of HKLM (requiring admin privileges): it occurs to me that [at least with a protection model anything like Windows'] this sort of thing MUST be limited for security reasons... after all, we are talking about a system account being used to delete or rename files - so there needs to be *some* restriction on the scheduling of such operations!
This differs substantially from the "Run*" type of requests - in that case, the operations in question are run *as a user* when that user logs in, so the normal access protections are in place.
Or at least this is my current take on this - I am still open to understanding the "why" better if this is not the actual reason. ;)
Anders
21st January 2009 22:22 UTC
"Another pitfall of the "it's for setup programs" principle is that the RunOnce key is processed only if a user with administrator privileges logs on" not sure if this is a HKLM only restriction
http://technet.microsoft.com/en-us/m...fidential.aspx
And yes, HKLM pending moves would have a problem if non admins could put stuff there. But clearly, MS should have added a pending moves key to HKCU and have userinit.exe or winlogon.exe do the operation at login time.
Maybe you should take a look at Live Mesh, it has shell extensions and stuff like that and installs/runs as non admin IIRC
RDaneel
21st January 2009 23:07 UTC
Hmmm... this is bizarre.
http://msdn.microsoft.com/en-us/libr...77(VS.85).aspx
says nothing about this restriction of RunOnce... in fact, it states explicitly and without qualification that "Run and RunOnce keys are run each time a new user logs in."
OTOH, Raymond Chen clearly knows his stuff, as any followers of his blog "The Old New Thing" will recognize.
I suppose it is indeed possible that the discussion from Raymond in your link is implicitly framed to be dealing with RunOnce entries under HKLM, and that RunOnce entries under HKCU do work the way I expect (and as my link explains).
If that isn't the case, I don't understand where that leaves us... :(
Anders
21st January 2009 23:09 UTC
well, you are just going to have to test HKCU then, I'm too lazy to do it ;)
RDaneel
21st January 2009 23:16 UTC
All right, I will fire up a VM, create a completely non-privileged user, and then try to construct a scenario that actually tests this meaningfully (it's non-trivial). ;)
RDaneel
22nd January 2009 02:47 UTC
I tried to "edit", but was outside the time window...
----
Grrr! It is actually much less trivial than I thought... as I tried to use my NSIS installer to set up this test scenario, I created a completely ordinary user ("Fred").
Fred then tried to run my installer, which of course next asked for an admin password... you can guess the rest. Of course the installer was from then on running AS the admin user whose password I had used - NOT as Fred any longer (and of course, NOT using Fred's tree in HKCU). :(
So even on the latest and greatest Windows (the one having a single-digit name), the access controls seem to be stuck in the Dark Ages... all my NSIS installer is looking for is to be able to DO certain things with an admin's PERMISSION - NOT BE THE *&^*%*&$&^$%& ADMIN!
I know I have asked essentially this question before, but are things really this bad? By its very nature, this entire mechanism of any installer needing admin permission no longer being able to properly install its app into the CORRECT per-user file and registry trees is completely broken.
It is sort of hard to believe that something this broken that sabotages the whole point of wanting to have PER-USER areas of the filesystem (and registry on systems that have one) would ever be shipped. :|
So what am I missing? Or are any solutions to this outside the scope of what NSIS (or any other non-MSI installer?) can do?
Anders
22nd January 2009 07:02 UTC
you are supposed to pick one:
a)admin aka all users install; install in $programfiles, and put global stuff in HKLM. All per user stuff must be taken care of by your app the first time it's run by a user, not the setup program
b)per user install; install in (local)app data and HKCU, you can not touch $programfiles or HKLM
to support both, you would use a custom page or something to let the user decide
there is also a hacky third option, if you use the UAC plugin, you can install as admin, but still be able to do stuff as the actual "interactive" user and not the admin used to elevate
RDaneel
22nd January 2009 08:03 UTC
Thanks, Anders... I will take your most recent comment as general advice to installer-writers - since all *I* complain about not being able to do is your "b)" option. ;)
That case is not really possible IF one has need of any of the "... on REBOOT" functionality of NSIS/Windows, since that facility uses HKLM. And while there are other cases, installers with Shell extensions will always be stuck with having to REBOOT from time to time. :(
OTOH, I will look into the UAC plugin you mention, since you imply that it can be used to borrow credentials while retaining the original user's identity. Sweet.