I figured this day would come, and to be honest, I'm a little bit surprised it took as long as it did for me to run into this in the wild. But this week, I finally came across an installer that somebody had devised which would check to see if UAC was turned on, and if so, it would fail out, and not install.
Actually, it was even worse than that. It would speak condescendingly to the user, informing them that UAC was turning on, so clearly the user must be some sort of an idiot. I mean, the readme file (which we all know everyone reads thoroughly multiple times before running an installer making sure they digest every last bit of it) clearly explains how to turn UAC off, how could they have missed that, or worse, ignored their sage advice?
Then the installer exited.
So, I took a peek to see how the application was performing this check. A little bit of time with Process Monitor was all it took - the application was looking at HKLMsoftwaremicrosoftwindowscurrentversionpoliciessystemenablelua. Aha - a registry key! That makes things easier.
So, I shimmed up the application using VirtualRegistry. Now, we don't have a command line argument for VirtualRegistry that says "lie about UAC" so I had to invent my own using ADDREDIRECT(HKLMsoftwaremicrosoftwindowscurrentversionpoliciessystem^HKLMsoftwarelieaboutlua), create this key, add the DWORD value enablelua, and set the value to 0. Now, the application thinks UAC is off, and we can go on from there to fix the LUA bugs that the developer punted on fixing.
Now, here's what I don't get. If the application really needs to have admin rights, checking for UAC being turned off is a really silly way to get that. While it doesn't make sense for most organizations to run as a standard user with UAC turned off, there are some who do. This check could lead you in completely the wrong direction. If you really need admin rights, then manifest as requireAdministrator. (Note that I can still go back and shim with RunAsInvoker to override your manifest, and then fix your LUA bugs myself, but at least you're checking the right thing then.)
There are, of course, other ways to check to see if UAC is enabled which would have made my job harder. I won't point them out, because that'll just make my job harder if somebody chooses to do that, and the obvious one has some of the same issues as this approach. All I can ask is this: if you're going to punt on fixing bugs, at least don't block me from fixing them for you. In this case, they didn't (though it looks like they tried) - and I figured I would share how to get around this in case others run into it.
So, the arms race has begun. Together, we can get applications running as a standard user. Because that's what our mutual customers want. But if you fight me, I'll just get trickier! 🙂