Windows: How can I find the LocalAppData directory for each user on a particular machine? - windows

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?

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?).

Related

How to change default value of AllUsersProfile environment variable.

I want to map default location of ALLUSERPROFILE to some other folder.
I am following below link but no luck so far
https://www.pcreview.co.uk/threads/changing-userprofile-and-allusersprofile.4047094/
I believe what you want is the registry key
HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProfileList.
The easiest way to do this is:
When installing Windows, create a temporary user account with admin rights.
Log in with the temporary account, change the default user profile directory, and restart (I believe the registry change doesn't take effect until you restart);
Log in with the temporary account and create the "real" / permanent user accounts. Make sure at least one of these has admin rights.
Log in with the "real" admin account and delete the temporary / dummy account you created during install.
If you have existing profiles you want to move, it becomes much more difficult, because
The registry change will not affect existing user profiles.
IIRC you cannot move existing profiles while Windows is running. You have to boot into a recovery mode console and use RoboCopy to move the user profile folder(s).
I think I remember seeing a detailed write-up on this somewhere. I'll try and find it later this evening.
But I would caution you that relocating user profiles after the fact is problematic.
For one thing, the public and default user profiles are set up on C: (or more precisely, your system drive) during installation. If you move the entire profiles folder, there are a bunch more registry entries related to those two profiles that will need to be changed.
Further, I've encountered a number of programs that assume the user profile folder is C:\Users. That is a stupid assumption, but it is likely to cause you problems.
You can mitigate some of these issues by creating a symlink or junction from C:\Users to D:\Users (or wherever you move the user profiles to). Then anything looking in C:\Users should be transparently redirected to D:\Users. That gets you out of messing with the per-user folder settings in the registry.
It should also be possible to move selected user profiles to another partition. That is, you would leave C:\Users in place, create a D:\Users folder, and then move selected user profiles -- i.e. move C:\Users\jane to D:\Users\jane. You'd still want to use RoboCopy to do the actual move ... and in this case you would need to alter the profile folder registry settings for any user being moved ... and I would also recommend creating a symlink from C:\Users\jane to D:\Users\jane. This is more work, but it's less invasive.
But I can tell you I tried one of the above approaches on a Windows 7 machine -- it's been a few years, so I don't remember which -- and ended up being unable to update to Windows 10 until I moved the/my user profile folder back to C:.
And I'm pretty sure while researching the problem I found that moving the Users folder is officially not supported by Microsoft. (I'm not clear on whether they still support setting an alternate folder at installation time by tweaking the Windows setup scripts.)
<update>
There is a similar question with several good answers on SuperUser. One of the answers links to this post on LifeHacker which describes the RoboCopy procedure in detail ... I believe that's the longer write-up I looked at a few years ago.
</update>
Yes, you can, in Windows, change the default user profile for all new users to another path. For example: d:\users
I explain it in detail in this post (in Castilian -Spanish-):
https://www.sysadmit.com/2021/01/windows-perfiles-de-usuario-en-d.html
Of the three ways that I explain in the aforementioned post, the simplest is done during the installation of windows. Is this:
create in the root directory of the windows installation media the file:
Autounattend.xml
With this content:
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<FolderLocations>
<ProfilesDirectory>D:\Users</ProfilesDirectory>
</FolderLocations>
</component>
</settings>
</unattend>
Perform a new installation with that installation medium and you will get as a result that ALL user profiles and directories will be in
d:\users
instead of the usual
c:\users

Change registry value permission command line or NSIS

I'm trying to grant ordinary users write access to a registry value I created.
They cannot have write access to the parent key.
Through regedit, it's simple:
1. Select value
2. Edit Permissions (change accordingly)
3. OK
However I'm struggling to do the same via command line or NSIS.
The command regini has a very nice method for changing key permissions. If this worked for changing value permissions, I could easily script it into my installer.
The NSIS plugin AccessControl has a very nice method for changing key permissions but no evidence of changing value permissions.
In this case, the key is HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run which I will not modify the permissions of.
How can I change only the permissions of the value I've created? How can I do this just as regedit allows, but silently through command line or NSIS?
The value would be something like:
[HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run]
"My Value"="C:\Please\Let\Me\Change\Permissions\Sadface.exe"
Note, this is for scripted software installer which build script will run on Mac, Linux and Windows (NSIS allows this). Recommendations for bundling special dlls or Windows executable is OK so as long as they're easily bundled and chained against at install time. Solutions including tools such as Windows SDKs cannot be accepted unless the footprint is small and so as long as the DLLs can easily be bundled and included into a LGPL 2.1 project. e.g. installing users will have to run this, so solutions need to be reasonably portable/distributable.
As #Noodles mentions in the comment above, it's not possible to change value permissions, so no solution exists. Registry editor is actually providing the key permissions, which is observable by looking at the Window title, and which is undesired for this particular solution.

Find out WHO made the last change to files by Powershell?

I have a shared network location for all users saving files. All users have full access to this location.
Is that possible to find out WHO made the last change to a file or folder by Powershell or any other way?
There is no issue to get all those date and owner info from Powershell, but looks like there is no way to find out WHO made the last changes.
any idea please?
The only user held against a file on NTFS is the owner. There is no record of who last modified the file.
However Windows can audit file system operations.
See http://support.microsoft.com/en-us/kb/310399 (says Windows XP in the title but applies to later versions). This needs to be applied to the system hosting the file system.

VS2010 Deployment Project: Issues with multi-user-install and registry entry

I have issues setting up my deployment project in Visual Studio 2010. Im using Windows 7 x64. Here's my problem:
The setup is supposed to install my program for all users. During the setup three registry keys are written to the HKEY_LOCAL_MACHINE/Software/Something folder, containing the setup variables for Serial, Name and Organization as values - [COMPANYNAME], [PIDKEY], [USERNAME].
What happens:
User1 (Admin) installs the software, entering his username, serial and company. Everything works. The keys can be found and values read by the program, using Registry.LocalMachine.OpenSubKey(path). The first thing I don't get is that I cannot find the registry entries, using the regedit.exe. Anyway, the code above finds them.
Now, User2 (Non-admin) tries to execute the freshly installed program. The installer is launched again, saying "Wait for ... to configure ...". The user specific folders for User2 are created correctly. The program is started, but the registry keys cannot be found by the program anymore.
Now, finally, User1 tries opening the program again. (The registry entries cannot be found anymore.) Edit: The registry entries are actually there, but its values are empty.
So, my questions:
Why can't I see the registry entries with regedit after the install, although they are obviously there?
(2. Why are the registry entries deleted, when the second user tries launching the program for the first time and how can I avoid that?)
Edit:
2. Why are the registry values set to empty strings, when the second user tries launching the program for the first time and how can I avoid that?
Cheers from Auckland and thanks!
Marc
You might be missing the registry entries if you have a 32 bit package installed on a x64 machine. In this case the registry entries would be redirected under "HKLM\Wow6432Node...". This is the standard behavior for x64 Windows machines. The same happens with the file redirection to Program Files and Program Files(x86).
That is strange. It could happen that the second launch of the installer, a normal automatic repair operation, has removed the registry entries by mistake. To get more details about the actions executed during the second launch I recommend you enable permanent logging on the OS.
http://support.microsoft.com/kb/223300
Wonder why the Find-function didn't find the keys though?
Probably the API used is considering the keys do not exist if all the values are empty. You should check its docs.
Obviously the "second installer" performs the entry again, without having values for that. Do you have an idea how to solve that?
This usually happens if the registry are written with values from public properties. During the automatic repair the properties don't have their initial install values so they are considered to contain an empty string, which is than used to replace the registry values.
The only solution you have is to make a small custom action that runs during repair, as immediate, which searches the registry entries before they get overwritten and places their values in the properties your are using. This way the overwrite operation will use the correct values.

Are dirs in C:\Users\Public\Documents writable to everyone by default?

I want my installer to create a folder in C:\Users\Public\Documents that will be readable and writable to all local users. This includes the right to create files/dirs there, and to modify and delete all existing ones. The installer is being ran as Administrator.
I don't have to programatically set the permissions for my dir, right? Just by creating the dir, it will have the correct permissions I think.
I'm interested in the behavior under XP, Vista and 7.
Note: I'm not hardcoding the path C:\Users\Public\Documents, I'm querying CSIDL_COMMON_DOCUMENTS from the Win API, which can return different values depending on machine and OS. For example on XP it returns a different path.
Edit: here's a relevant discussion. It points to MS docs about the question, but it also looks like those docs may be wrong.
Yes, it inherits rights from the parent folder. Which has write permission for anybody in the INTERACTIVE group. Which includes any logged-in user account.
Use the Security tab in the shell's Properties dialog to review these settings.

Resources