8

I have a c# application on Windows 10 PC. There are settings files in the install folder (C:\Program Files (x86)\xxx) which I want to read, but not edit unless user has admin access. The problem is that windows is copying these settings files to the VirtualStore and redirecting all reads there - whereas the same app run as admin sees the original settings files in the Program Files folder.

My question: Is there a way to make the application see the original files in the Program Files even when not run as admin? I just want to read them, not edit them.

Sugrue
  • 3,629
  • 5
  • 35
  • 53
  • If you are only reading them, what is the problem with reading a copied version of that file? – ChrisBint Oct 21 '16 at 09:00
  • Because when run as admin, you can edit them - but in this case it edits the versions in the program files folder, not the virtual store versions. So from the point of view of the non-admin instance, the files aren't changed. – Sugrue Oct 21 '16 at 09:03
  • At what point does it copy the files? – ChrisBint Oct 21 '16 at 09:09
  • Windows seems to make a copy to the virtualstore at the moment the non-admin instance accesses the files. – Sugrue Oct 21 '16 at 10:13
  • Your program is not compatible with UAC. Pretty hard to do these days, you need to document your VS version. And you need to explain your "just want to read them" claim when the program is clearly also writing the file. – Hans Passant Oct 26 '16 at 15:40
  • UAC - really? Why is older technology always written off with that swear word? Let's pretend to be Microsoft and introduce a "new since Vista" OS virtualization tech that is supposed to be "transparent to the application". Why are so many applications breaking then? NOT a fan! – Mark Ronollo Dec 14 '22 at 21:34

2 Answers2

7

You don't need elevated permissions to read the file from Program Files (x86) folder. Check how you open the file for reading. You should specify different FileAccess flag in common user mode and in elevated mode. For common user mode it should be opened with 'FileAccess.Read`:

using (FileStream settingsFile = new FileStream(@"C:\Program Files (x86)\xxx", FileMode.Open, FileAccess.Read))
{
  // Do the job
}

To detect if application runs with elevated permissions use IsProcessElevated method. Depending on the result you are able to select proper FileAccess mode.

Community
  • 1
  • 1
Nikita
  • 6,270
  • 2
  • 24
  • 37
  • Thanks - I'll double check that I'm opening the file correctly. – Sugrue Oct 27 '16 at 13:29
  • 1
    @Sugrue To understand your application's file traffic better you could use [`Process Monitor`](https://technet.microsoft.com/en-us/sysinternals/processmonitor.aspx) from Sysinternals suite. It will show desired access for each file requested by application. – Nikita Oct 27 '16 at 14:33
  • 1
    Hi Nikita - we double checked - and we were being stupid in another section of code, where it was opening the files incorrectly. All fixed now. Thanks, – Sugrue Nov 01 '16 at 11:19
1

The way to see original files in Program Files is to not write there (and to that end open files for read-only as Nikita points out). The VirtualStore is not there to be used, but to fix application issues. Such issues are caused for example by broken applications written for old single user Windows when current day Windows (since NT) can have multiple sessions concurrently from different users.

If an application wants to modify data files shared between all users, it should save the files to All Users Profile. If it is user data, it can store the data in Application Data folder in the user profile. In the Application Data you are still left with the option if you want the data to be Roaming or Local.

The paths to these folders are different on different Windows versions. Windows Installer has properties set to the paths. Applications have many interfaces they can use. See Working with Known Folders in Applications and SHGetKnownFolderPath for one interface.

Other than that, the access to Program Files is behind UAC. You should read on it to get all details right.

Marko Kohtala
  • 744
  • 6
  • 16