Unanswered Active Setup Limitations under Windows 7?

  • Wednesday, April 06, 2011 10:05 PM
     
      Has Code

    I am working on a very large deployment project for a client and have come up against an issue that I haven't been able to work around.  I have whittled away at the complexity until I arrived at this incredibly simple issue: Windows 7 seems to have severely restricted what can be run via the StubPath in Active Setup.

    This probably isn't the correct forum for this question but I can't find any deployment/msi forums in any of the lists by browsing.  If you know of a good forum for this question then please point me there or if you are a moderator then feel free to move this post.

    The basics of my situation are:

    • The package will be distributed via SCCM or some other home grown deployment tool while no users are logged into the desktop machines.
    • The package has been carefully designed to separate all the user vs. system object (files and registry items) into appropriate MSI components.
    • All the 'user' objects live in components that use an HKCU registry item as the KeyPath.
    • We can't use self healing because there aren't any advertised shorcuts, etc. in our product.  This is a vsto (local) project that needs data files in %appdata% and per-user registry configuration to function. 
    • This installer works great as a stand-alone installer when an administrator runs it on both XP and Windows 7.
    • The installer runs great under Active Setup on XP, even for a non-admin user.
    • The installer is never invoked by Active Setup on Windows 7, regardless of the rights of the non-primary installing user.  In other words, not even users who are administrators get the repair install under Active Setup.
    • If a non-admin user logs in after the product is installed by an administrator then they can open a cmd window and do a repair install with exactly the same command as I am using in the StubPath and it works flawlessly, no warnings.

     Here is what my HKLM\Software\Microsoft\ActiveSetup\InstalledComponents\{...product code...} registry looks like:

    Default (REG_SZ): NotReallyMyProductNameButYouGetTheIdea
    Locale (REG_SZ): *
    Version (REG_SZ): 3,0,0,1
    StubPath (REG_SZ): msiexec.exe /fup {...productcode...} /qn
    

     

    This works great on XP for all users.  I can do the initial install under an administrator account or as a simulated SCCM install under LocalSystem (using schtasks or the at command) and every user that logs in gets the repair install - both users and admins.

    On Windows 7, however, absolutely nothing happens when a new user logs in. 

    Well, that isn't entirely true.  I know that Active Setup has run and has visited my HKCU key.  The new user does get the following registry keys under their HKCU\Software\Microsoft\ActiveSetup\InstalledComponents\{...productcode...} hive:

     

    Default (REG_SZ): (value not set)
    Version (REG_SZ): 3,0,0,1
    

     

    The installer, however, never runs.  I have looked in the event log for a security warning, in the application event log for a notice that msiexec tried to run and failed. 

    Here is the interesting thing.  I can change our StubPath in the HKLM hive to:

    StubPath (REG_SZ): Notepad.exe

    and that pops up for all users when they log in.

    What I can't do is change the StubPath in the HKLM hive to:

    StubPath (REG_SZ): msiexec.exe /?

    When I try that nothing happens - no window pops up, nothing.  I have tried all sorts of things (using a fully qualified path to msiexec, putting the msiexec repair install command into a batch file, etc.) and nothing seems to help.

    So my very simple question is this: What restrictions are placed on the StubPath command under Windows 7?  Do they differ for admin users and non-admin users?

    Thanks for any help and pointers to help that anyone might have.  We are up against the wall on this and I need to figure this out fast.

     

     Dave

     

     

     

     

     

     

All Replies

  • Thursday, April 07, 2011 4:40 AM
     
     

    I am glad that you highlight this problem Dave

    I face exactly the same problem with Registry settings that should be applied to every users trough Active Setup.

    What used to work without any problems under Windows XP (regedit /s drive:\path\file.reg), is not working as expected under 7. An annoying UAC dialog box is showing up, when a user opens a session, while trying to execute an Active Setup command.

    However if I disable UAC then it is working well. So your problem might come from the restrictions related to UAC. You should try to test your package with UAC disabled and see if the result if the same.

    Today I will try another solution, by launching a batch (trough active setup) which will disable UAC, modify my registry settings, and re enable UAC.

    However I guess I will have the same problem, as launching the batch will probably need elevation, which will cause UAC to display... I'll let you know about the result.

    Hopefully someone already found a solution to this issue which I believe many packager had already face.

  • Thursday, April 07, 2011 9:13 AM
     
     

    Hi Dave,

     

    Finally I found an excellent post:

    http://www.vistax64.com/vista-security/73869-standard-user-needs-regedit-uac-prompt.html

     

    I will quote John Brush in his first post,

     

    Hello,

    Regedit should not be prompting if you are a standard user.

    In any case, this should help you out:

    Using regedit, browse to:

    HKEY_CURRENT_USER\Software\Microsoft\Windows
    NT\CurrentVersion\AppCompatFlags\Layers

    Create 2 string values in this folder, named:

    c:\windows\regedit.exe

    and

    c:\windows\system32\regedt32.exe

    double-click on each of these items, and set their value to:

    RUNASINVOKER

    It works for me. I guess you could try the same by creating a key for msiexec.

    Besides I think these article might interest you as well:

    Using Windows Installer with UAC

    http://msdn.microsoft.com/en-us/library/Aa372468.aspx

    Guidelines for Packages

    http://msdn.microsoft.com/en-us/library/aa368772.aspx

    Let me know if it is helping you.

     



  • Thursday, April 07, 2011 10:37 PM
     
     

    You might get a chuckle out of the "solution" I finally settled on.  Or if you are a sane person you might go screaming for the hills.  I haven't decided if it makes me want to laugh or cry.

    To recap my problem, I couldn't get ActiveSetup on Windows 7 to invoke my StubPath in HKLM for new users if it included a reference to msiexec.exe.  That meant that ActiveSetup on Windows 7 was effectively busted for me.  New users never got the repair install and therefore never got the product 'installed' for them.  I can't alter the rights for any system objects (like the installer service or RegEdit) because these are very tightly controlled corporate images.

    What I did was write a tiny native C++ app that takes a product code as a command line parameter and calls CreateProcess on msiexec  with the appropriate flags (/fpu /qn) and the passed in product code.  I install this tiny application in <program files>\MyProduct just like every other binary in our product.  I then make my HKLM StubPath point at this tiny application instead of msiexec.  I pass in the [ProductCode] property so it is reusable the next time I have to deal with this nightmare.

    And this works.  Believe it or not, this works for administrators and restricted users on 32 bit and 64 bit XP and Windows 7.  At least it works in test - I haven't turned it lose on the users yet.  Exactly why this works but invoking msiexec directly doesn't work is a mystery to me.  Still kind of cracks me up.  You might find that you can use a similar approach to your problem: write a tiny stub application that will create the HKCU keys programmatically, install that application along with your product and use that as your StubPath.

    Here are some other random thoughts (rants?) on Active Setup and installing under Windows 7.

    Installers are the biggest Torjan horses I can imagine.  We ask the user if we can have their permission to alter their system in fundamental ways - install drivers, update .NET, add security tokens, delete security tokens, add and remove users from groups, install, start and stop services, etc.  The user says yes and off we go.  So what, exactly, is the point of putting choke points in the way?  As my little sleight of hand above shows, if you give my code permission (elevated) to install binaries on your disk and alter the OS then there really isn't anything it can't do.  If my proxy-msiexec trick didn't work then I was going to write and install a tiny service to do the job.  If I can install and start a service to run as LocalSystem then there isn't really anything on the box that I can't get to.  Can't get at it from a service?  Install a file system filter driver.  But why make this artificially difficult?

    My next big issue to solve is this: how do you uninstall an ActiveSetup application in Windows 7?  It is difficult enough in XP but seems impossible in Windows 7.  In XP I have some custom actions that run on uninstall that walk the HKLM\Software\Microsoft\Windows NT\ProfileList to identify all the possible users on the computer.  For each of these, I get their %appdata% path and nuke our product's user's files.  Next up I then take a crack at the HKCU registry keys.  Some of the users are going to be logged in and I can get to their keys via HKEY_USERS.  Some aren't logged in so I have to do a RegLoadKey on their ntuser.dat and get to their keys that way.  Huge amount of work to clean up after ourselves, but some of our data files are quite large and we can't leave them behind.  What's worse is that some of our HKCU keys can cause issue if orphaned.

    Why couldn't ActiveSetup be more 'active'?  Why not have the ActiveSetup code do some sort of registration when a user logs in so that it is easier to find these keys and files on uninstall?  Or better yet, why not have ActiveSetup merge the file and registry install actions into the cached MSI database so that uninstall just simply takes care of them like it takes care of everything else?  Yes, this would tie ActiveSetup to MSI instead of allowing for a generic StubPath (or in the case of Windows 7, and anti-MSI StubPath) but it would make it a whole lot more useful. 

    So if I already have uninstall figured out and coded up, then what's the big deal? The process I just outlined above doesn't work on Windows 7.  It doesn't work on Windows 7 (actually Vista+) because the msiservice on no longer has the SeBackupPrivilege.  That means that custom actions don't have the SeBackupPrivilege, even those running as deferred actions in the system context. That means that custom actions can't call RegLoadKey and therefore can't clean up logged-out user's HKCU registry entries.  

    I suppose this wouldn't be a big deal - just some more debris floating around in the registry - except that I am trying to uninstall VSTO (vstolocal) addins for Office.  The users get these keys via ActiveSetup so the addins work for everyone when SCCM pushes the application out to the machine.  Unfortunately when the administrator (or SCCM) uninstalls the addin from the machine everyone is welcomed to work in the morning with 'Failed to load addin <foo>' when they open Office apps.  Lovely.

    Ok, that's all I have to rant about right now.    

    If you have any thoughts or ideas about how to fix uninstall on Windows 7 or why my proxy-msiexec works when msiexec doesn't then I would love to hear from you.  I will take a look at the links that you included (the Guidelines for Packages looks particularly good) and I will let you know if they help.

     


    Dave Brooks Principal, Installer Factory, LLC dbrooks@installerfactory.com
  • Monday, May 02, 2011 4:11 AM
     
     

    Sorry  for the late reply Dave, I have just seen your last post today. Did you solve your problem?

    Anyway I think this article could help you as it is giving 3 different methods of using ActiveSetup with MSI:

    http://www.symantec.com/connect/articles/guide-msi-healing

    Cheers

  • Wednesday, May 11, 2011 3:14 PM
     
      Has Code
    Have you tried:
    [SystemFolder]msiexec.exe -fpu [ProductCode] -qn
    note the SystemFolder property. I have seen working Active Setup on Windows 7 Enterprise with UAC enabled.
    • Edited by Pók Wednesday, May 11, 2011 3:20 PM Formatting
    •