Windows 10 Best Place for Sharing Data between Multiple User Accounts - windows

I'm converting a suite of legacy 32 bit C++ apps to run under Windows 10. These apps can run under different user accounts on the same PC and need to share the data between themselves and all the users. Some of the apps are Windows services, some are regular UI apps. There's a lot of communication between the apps and sometimes this is accomplished using shared data files. All the different user accounts need to access the shared data...
I have tried storing the shared data in C:\Program Files (x86)\Common Files\AppName\data
and have set the security level on that folder to Full Control for All users.
Most of the time, this works perfectly well. But occasionally, at seemingly random intervals, one of the shared data files ends up in:
C:\Users\UserName\AppData\Local\VirtualStore\Program Files (x86)\Common Files\AppName\data
I have tried to replicate this, and it never happens when I'm looking...
If I run a simple UI app that just writes to this folder, everything is fine. The App does not need to run with elevated privileges to write to the folder.
I suspect it's when one of the Apps is trying to write to a file that is locked by another, which the code handles by using exceptions, but Windows tries to help out by writing to the VirtualStore instead. But I could be wrong...
So, to cut to the question:
Where is the 'best place' to store shared data between several apps AND user accounts, that won't end up in the VirtualStore?
Andy

Any application with a requestedExecutionLevel node in its manifest is marked as Vista compatible and the redirection to the Virtual Store is disabled.

Related

visual studio setup project - install for all users

I have a visual studio setup project which installs my files to the program files folder and also writes some stuff into the registry and in addition some of the files are com visible (so there is more confusing stuff written to the registry).
Therefore I have to install it as an administrator - this works fine. And this administrator and every other administrator is able to start the program. But using a standard user I am not able to start the program.
All registry entries are there for the standard user - and it also has enough rights to access the file in the Program Files folder.
Could there be a problem with the ComVisibility? (Which is needed because it's actually a DLL working as a plugin for Solidworks)
You just need to look at the code in your app and see what it does that limited users can't do. Installing it for all users does not mean that it automatically allows limited users to violate security. Just find out what it's doing when it gets the security error (which is what you believe it is).
Limited users have never been able to write to restricted areas such as the ProgramFiles folder, CommonFiles folder, HKLM etc. That's a common reason for limited user issues with apps.

How to prevent file redirection to VirtualStore for read/write files?

I am using C# with .net 2.0
I am saving my program data in a file under: C:\ProgramData\MyProgramName\fileName.xml
After installing and running my application one time I uninstalled it (during uninstallation I'm removing all the files from "program data") and then I reinstall the application, and ran it.
The strange thing is that my application started as if the files in program data existed - means, I had old data in my app even though the data file was deleted.
When running:
File.Exists("C:\ProgramData\MyProgramName\fileName.xml")
I got "true" even though I knew for sure that the file does not exist.
The thing became stranger when I ran the application as admin and then the file didn't exist.
After a research, I found out that when running my application with no admin privileges instead of getting:
C:\ProgramData\MyProgramName\fileName.xml
I get
C:\Users\userName\AppData\Local\VirtualStore\ProgramData\MyProgramName\fileName.xml
and indeed there was a file that existed from the previous installation (that I obviously didn't delete, because I didn't know it existed).
So just guide me how could I stop this when apps running with no admin right.
I do not want to create any file automatically in VirtualStore folder. Please discuss all the possible ways to stop this.
First, ask yourself, do this need to be globally saved for all users?
If it doesn't have to be, save the file in Application Data instead, you can get the path with Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), it should always reliably expand to C:\Users\Username\AppData\Roaming\. Do note that this path is unique for each user though.
If you have to, you're out of luck. There is no reliable way to store application data for all users without admin rights (or UAC) on any Windows post-XP that's not extremely hacky, like storing your data in the Public user (which may or may not be possible, I can't check right now).
An approach to solving this is to use the Environment.SpecialFolder.CommonApplicationData location, but with some very important caveats & setup.
CommonApplicationData is
The directory that serves as a common repository for
application-specific data that is used by all users.
This location is described further here and here.
Important requirements and restrictions are given in another SO answer: https://stackoverflow.com/a/22107884/3195477
which said in part:
The recommended solution is for your installer to create a sub
directory of C:\ProgramData for your shared storage. And that sub
directory must be given a permissive ACL by the installation program.
That is what grants the desired access to all standard users.
Otherwise the program running with standard user permission will still not be all equally able to read/write files in that location for all users.
I found a work around for this issue when transferring a very old win32 app to windows 7 & 10. The program wrote to a database on C:\Program Files... but the OS auto changed the path to virtual store. However the database was required globally. By changing compatablilty mode to Windows 95 or XP SP2 and always running as administrator the database was worked on directly in C:\Program Files\etc.
There are security implications for this and the box was removed from all networks and adapters disabled etc.

Where is the guideline that says you shouldn't write to the Program Files area?

Many questions on SO say "Windows developer guidelines" or "windows design guidelines" say that you shouldn't write temporary or program data to the Program Files area, but as far as I can tell none of them actually link to a piece of documentation that says as much. Searching the MSDN has yielded me no results. Windows will make the area read-only, so it can be enforced by the OS, but that doesn't mean developers didn't try to write there anyway (e.g., when porting older, XP and earlier based programs forward.)
I realize that it seems odd to ask about it this late into Windows development (since, as a commenter below pointed out, has been enforced by the OS for more than a decade), but a document that says so is sometimes necessary to satisfy people.
With that in mind, Does Microsoft have a document published stating we shouldn't write application data to the Program Files area, and if so, where is it?
From Technical requirements for the Windows 7 Client Software Logo Program:
Install to the correct folders by default
Users should have a consistent and secure experience with the default
installation location of files, while maintaining the option to
install an application to the location they choose. It is also
necessary to store application data in the correct location to allow
several people to use the same computer without corrupting or
overwriting each other's data and settings.
Windows provides specific locations in the file system to store
programs and software components, shared application data, and
application data specific to a user:
Applications should be installed to the Program Files folder by default. User data or application data must never be stored in this
location because of the security permissions configured for this
folder (emphasis added)
All application data that must be shared among users on the computer should be stored within ProgramData
All application data exclusive to a specific user and not to be shared with other users of the computer must be stored in
Users\<username>\AppData
Never write directly to the "Windows" directory and or subdirectories. Use the correct methods for installing files, such as
fonts or drivers
In “per-machine” installations, user data must be written at first run and not during the installation. This is because there is no
correct user location to store data at time of installation. Attempts
by an application to modify default association behaviors at a machine
level after installation will be unsuccessful. Instead, defaults must
be claimed on a per-user level, which prevents multiple users from
overwriting each other's defaults.
And I'm quite sure that there's similar stuff for every Windows version of the NT family going back to Windows NT 4 or even earlier.
See also this question.
Edit: the original link in this post to the Windows 7 Logo program exists no more. Here you find the current link to the Certification requirements for Windows Desktop Apps. See Section 10, Apps must install to the correct folders by default
In later versions of windows (Vista, 7 and of course server versions) access permission are restricted for "special folders" including "Program Files". Even if your program is elevated to have sufficient privileges to write to this folder it is still a bad idea.
I don't know of any guidelines that state this but there is a list of special folders and what they are meant for. The fact that there is a special folder for nearly all types of data I can image means there is no need to use the program files folder.

TFileListBox Component Finding Files Which No Longer Exist

I am using Delphi 7 on Windows 7 and have an application which uses a TFileListBox component to iterate through files in a directory and copies them to a backup directory.
I'm experiencing some strange behavior whereby the TFileListBox is detecting files which do not exist within the directory?? The directory I am coping from contains 75 files but the TFileListBox detects over 100 files.
I changed my explorer settings to display hidden/system files but still cannot see where these extra files are coming from.
I was wondering whether this Windows 7 Previous Versions was playing a part in this problem as I am fairly sure that the extra files the TFileListBox is detecting did used to once reside in this directory but were deleted...
Any help on this would be much appreciated.
We have worked out from the comments above that the issue is related to the Virtual Store which is used when your application is virtualized. The virtual store was introduced with Windows Vista as part of the move to running applications without administrator rights. These files are appearing in the virtual store because your application is writing to the program files directory, to which standard users do not have write privileges.
Virtualization was introduced to help deal with legacy applications that were not going to be recompiled to take account of the new Vista policies. Nowadays you simply should not be building a virtualized application.
You can disable virtualization by linking an application manifest to your application that includes the <requestedExecutionLevel level="asInvoker"/> section.
When you do this, you will no doubt find some other problems because your application may attempt to write to the program files directory, the HKLM section of the registry, etc. Whilst it may seem painful to make these changes, they are worth the effort.

How do I update a VB6 app from XP to Vista?

I work on a vb6 application which is having problems with Vista, for the obvious reasons (writing to program files, and other things that are no longer allowed by default).
Where should I store application data or user's saved files?
Do I need priviledges to create folders and files, there, too?
What other common actions will cause problems?
The program has an updater which must download and register files, how do I elevate priviledges when this occurs?
Some of these questions have obvious answers, but I want to get the obvious stuff right.
Depending upon what you are doing, you might be in for a world of pain. There are no hard and fast answers to any of those questions, but from someone who is going through the same issues right now, here's what I know.
1) Where should I store application data or user's saved files?
This depends on what you are wanting to do. If you want them per user, store them in Users/AppData, if you want them for all users, store them in Common/AppData
If SHGetFolderPath(0, CSIDL_COMMON_APPDATA, -1, SHGFP_TYPE_CURRENT, sTempPath) = 0 Then
sCommonAppdata = Left$(sTempPath, InStr(1, sTempPath, Chr(0)) - 1) & "CompanyName\AppName"
End If
Change that to CSIDL_APPDATA for the Users AppData directory. Note: These map to totally different places on the filesystem for XP and Vista so when you are debugging prepare to look in different places.
2) Do I need priviledges to create folders and files, there, too?
You need Adminsitrator access to write anything in Program Files, if at all possible don't do it! We are currently running into issues that the API's for VB and the standard API's behave differently on files in Program Files.
3) What other common actions will cause problems?
There are lots of hidden gotchas. Just to name a few, you cannot communicate through IPC or Named Pipes to other applications (we have a Service that we were talking to through a Tray Notification Icon and that had to be completely re-written). Anything were you see a UAC notification is very difficult. Also you cannot write to anything in the Registry in LOCAL_MACHINE without Administrator, so you either have to stick to LOCAL_USER or raise credentials (see below).
4) The program has an updater which must download and register files, how do I elevate priviledges (sic) when this occurs?
Good luck with this, I highly recommend that you don't write it in VB6, like I said, the VB6 file api's appear to access files differently from the standard API's. If you need to elevate privileges see this post that someone kindly helped me with.
In the sort term turning off UAC and installing the ActiveX installer server will help. Long term you need to put data and configuration information in the users directory under \users or in \programdata.
In the short run it might not be necessary at all to modify your application, because
Vista comes with a set of compatibility options to allow legacy applications to run. This includes file and registry virtualization, a feature which basically redirects write operations to protected folders such as C:\Program Files to a virtual location only visible for the specific application running in a compatibility mode.
Some more details are mentioned in this article: How To Manage Windows Vista Application Compatibility in Dr. Dobb's.
Karl Peterson wrote a nice article on where to store user data & app data, with a VB6 class that retrieves the location of the special paths for you.

Resources