views:

2916

answers:

1

First, some background:

Our product needs to integrate with the Lotus Notes client by adding or updating a line in the NOTES.INI file.

We don't have a problem if we're dealing with a single-user installation of Notes (i.e. if there are multiple Windows users on the machine, they'll all use the same Notes configuration). In this case, there's a single NOTES.INI file in the Notes installation directory.

However, under a multi-user installation of Notes (where each Windows user has their own Notes configuration), each user has their own NOTES.INI file stored in the user's LocalAppData directory - e.g. C:\Documents and Settings\Username\Local Settings\Application Data\Lotus\Notes.

So here's the problem: If our product is being installed on a machine with a multi-user installation of the Notes client, we need to be able to update the NOTES.INI file in the profile of each user on that machine.

We can do this by having a program run when users log in, which checks whether that user's NOTES.INI file has been updated yet and if not, updates it. However, the uninstall process for our application needs to be able to reverse these modifications for all users on the machine.

Hence the question: assuming our code is running with local admin rights, is there some way that we can iterate through each user's profile and find their LocalAppData directory so we can make the necessary changes?

Any suggestions greatly appreciated :-)

EDIT 2009-03-25 16:52 GMT:
Looks like I have a possible approach (thanks Martin C):

    For each subkey of HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList:
      If it's a "real" user (determined somehow):
        Remember the subkey name - that's the user's SID
        Read the ProfileImagePath value
        If the user's Registry hive is not already loaded (i.e. there is no subkey of HKEY_USERS with the appropriate SID):
          Enable the SE_BACKUP_NAME and SE_RESTORE_NAME privileges
          Load the hive from ProfileImagePath\NtUser.dat using RegLoadKey
        Try to find the user's LocalAppData folder using each of the following Registry keys in turn:
          HKEY_USERS\<SID>\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
          HKEY_USERS\<SID>\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
          HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
          HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
        Expand environment variables in the resulting path if necessary (presumably just expanding %USERPROFILE% to the ProfileImagePath we got earlier)
        Use the path to find the user's NOTES.INI file and make the appropriate changes
        If we had to load the hive:
          Unload the hive using RegUnLoadKey

I can probably get that coded up, but it seems a tiny bit fragile and there's potentially a number of ways it can go wrong. Anyone have a more "official" approach?

+1  A: 

You can enumerate the sub-keys of

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList

Each subkey contains the "ProfileImagePath", which will point to the base-path of the profile. Dependent on the OS-version and the language setting you can then determine the location of LocalAppData (beware, it is language-dependent!).

Edit: A possible starting point for going further could be

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders

Unfortunately this could vary from user to user and HKEY_USERS only contains the keys of users which have loaded profiles. You could try if you could load profiles somehow (maybe one can attach a user's registry somehow if it is not already loaded to HKEY_USERS?).

Martin C.
Thanks - that's a good start. Our app is localized in 14 languages, so we'll definitely need to be able to support non-English versions of Windows. Is there any way to ask the OS what it thinks "Local Settings" and "Application Data" should be in the current language?
Anodyne
You could look at "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" and use the "Local AppData" key. I don't know if this could vary between users, but it could be a start.Beware, that especially the "My Documents" could be redirected by a group policy.
Martin C.
Hmmm... according to http://support.microsoft.com/kb/297060 it's possible to load a user's Registry hive using RegLoadKey, as long as your access token has the SE_RESTORE_NAME privilege enabled.
Anodyne
Encouragingly, the "User Shell Folders" key is actually DOCUMENTED here: http://technet.microsoft.com/en-us/library/cc787260.aspx
Anodyne
OK, I've just found a fairly serious problem with this approach. Windows Installer 4.0 on Vista doesn't give custom actions the SE_BACKUP_NAME privilege, so this approach won't work on Vista.
Anodyne
Sorry, should have linked the source for that last comment: http://blog.deploymentengineering.com/2006/10/vista-deferred-ca-consideration.html
Anodyne