TFileListBox Component Finding Files Which No Longer Exist - windows

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.

Related

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.

How do I make my program work in Windows Vista and Windows 7?

I have an application written in Delphi 2006 that was working fine in Windows XP. I packed the application using Inno Setup, using Program Files as the default folder. A few users migrated to Windows Vista and Windows 7. The issue here is that the application creates some files inside its installation folder by its own. This was working in XP but in Windows Vista the users were having problems with the created files (they don't appear and so on). After investigating the users' reports I discovered KB 927387: "Common file and registry virtualization issues in Windows Vista or in Windows 7."
Running the application with administrator rights just solves the problem, but that is (I think) an awful workaround. I would like to know if there are any directives or tips for making the application compatible with Vista and 7, because more users will migrate to these OS soon.
You need to re-write your application to store its files in the proper locations, even in XP, but especially in Vista onwards, particularly if UAC is enabled. This is becoming more and more important to get right as Microsoft keeps locking down and enforcing its security models with each new OS version. The rules for how to properly manage application- and user-related files is documented on MSDN, for example: "Application Specification for Microsoft Windows 2000 for Desktop Applications, Chapter 4: Data and Settings Management" and "Application Specification for Microsoft Windows 2000 for Desktop Applications Appendix A: Best Practices" (yes, they are old, but are still quite relevant). Look at SHGetSpecialFolderLocation(), SHGetFolderPath(), SHGetKnownFolderPath() and other related functions to help you.
For Vista/Win7, your app can't put the files in a subfolder of Program Files / Programs unless UAC is turned off or the app is running as elevated. Note that "elevated" does not necessarily mean "logged in as Administrator." Non-administrator users can elevate, and Administrator isn't necessarily elevated.
If the app does attempt to write to Program Files but is not elevated, the OS will either block the app or "virtualize" the write (put the files somewhere else), depending upon how UAC is configured. Neither one helps the app succeed at what it was trying to od.
So it needs to put them somewhere else. Where depends on why the files are being created, and you haven't told us that. You can read this article to learn about the options. Note that in addition to the user's AppData and Roaming folders, there is also an "All Users" (shared) profile.
You should probably look at this article and screencast, which discusses UAC in depth from a Delphi point of view.
Files you create for use by your application other than at installation time should go into the ProgramData directory if its global to the workstation, or into the users ApplicationData directory if its specific to the user.
For cases where you absolutely must place a file in the program files directory, you can use com to request elevation. This is discussed in great detail, and delphi specific bits are also available. One example that I have used this is in patching my users installation base. They are warned by UAC that the system needs to make changes, so if your doing this as an automated task, you might need to rethink the logic to be more user driven.
Here is another article, by Zarko Gajic, which shows how to get different system directories. Also have a look at this related question.
I had a similar enquiry here (Stack Overflow).
In the end I realised that I needed to put my application into Program Files at install time (requiring UAC/elevation) and then store my app's data in the user's App Data folder. I had to change the way my program generated 'default' configuration settings and also where I was saving this stuff, but it was worth the effort in the end - we ended up with something that installs and runs fine on XP, Vista and Windows 7.
The only UAC hit we get is at installation time, which makes sense to me (and you get a similar hit at install-time on the Mac too). We didn't have any data that would be common to all users in this particular case but I would have looked at the Program Data special folder if that had been the case.
The installer software we use (Setup Factory) made this fairly straightforward (we just wrote a small bit of code to detect XP versus Vista/Win7 and choose the right special folder accordingly). It would be easy to do this in Inno Setup too, from what limited experience I have of it.

Is AppData now the 'correct' place to install user-specific apps (which modify their own data)?

I'm probably just being very thick here, but it's not clear to me where I'm supposed to install 'new' user-specific programs on Windows 7 (and presumably Vista too, though I've not specifically looked at that scenario yet).
Under Windows XP (rightly or wrongly) we always installed our programs into folders under 'Program Files' and accepted that they'd be kind-of available to everyone. From what I can gather under Windows 7 I'm supposed to install my software under the user's AppData folder (possibly AppData\Local\MyApp). That makes a degree of sense, but the fact that this folder is 'hidden' by default means that we're going to have 'fun' talking our users through support stuff.
I want to install our software so that it's user specific (the Users bit in Windows 7 makes perfect sense) but I do want the user to be able to access it if required. Our program also includes a 'data' subdirectory which it needs to write into while it's running (embedded database), but as the program is intended to be single-user/standalone, the data folder being inside a user-specific folder isn't going to be a problem.
My problem is just that whole 'hidden folder' aspect of AppData. As much as I've trawled the MSDN, I can't work out where else I'm supposed to install user-specific programs. Taken one way it would seem to be something like AppData\Local\MyApp, and another way it would seem to be just as valid under the user's My Documents\MyApp equivalent.
Has anyone got a clear guide for where all this stuff goes? I found the MSDN docs confusing. :-)
Not really.
The directory that serves as a common
repository for application-specific
data for the current roaming user.
AppData is, surprisingly, for application data, not for installation (Click Once/Silverlight applications aside). You can, and should still install into Program Files, just don't expect to write into that folder.
You can install software into AppData if you want it to follow a user about in an Active Directory environment, which happens if you put it in AppData\Roaming (the SpecialFolder.ApplicationData location).
You can also install into AppData if you want the software to be available to just the user that installs it. This can be useful if, for example, you have multiple users on the same machine, who all want to run different versions of the software in complete isolation.
If you want settings to only apply on the local machine then you use AppData\Local, which is SpecialFolders.LocalApplicationData - this will make AD administrators very happy as the roaming profile size won't suddenly jump up 50Mb or whatever the size of your software is.
If you wanted to create settings which apply to all users then you're looking at SpecialFolders.CommonApplicationData
You should remember never to rely on the actual name of the directory - localisation issues mean this can change and the location does change with OS versions two. You should be using the special folder enumeration in your software, or the equivalent in your installer.
Could you not install into Program Files, but use AppData as it's supposed to be used, and store your database in there?
Windows 7 added the FOLDERID_UserProgramFiles known folder and by default this maps to %LOCALAPPDATA%\Programs. This is used by MSI when ALLUSERS=2 & MSIINSTALLPERUSER=1.
On Vista and earlier there is no canonical per-user application folder but just using %LOCALAPPDATA% is pretty common. Sadly MSI will just use %ProgramFiles% on these systems.
It's 2019, and I just installed Visual Studio Code (a Microsoft product) in the default folder of
%userprofile%\AppData\Local\Programs\Microsoft VS Code
This is probably for getting around the requirement to have an administrator or UAC prompt authorise the installation
Windows 7 folder structure is deeply inspired on Unix structure:
/usr/ -> C:\Program Files\ -> binaries: executables and dynamically linked
/etc/ -> C:\ProgramData\ -> global settings
/home/ -> C:\Users\ -> a folder for each user
~/.* -> C:\Users\Hikari\AppData\Roaming\ -> settings for each user
Windows has more folder, like My Documents for files with content produced by user, AppData Local and Roaming (which Unix usually handles with NFS).
It's about time for us developers to start using these structures. We must separate at least binary files that don't need to be replicated, global and user settings.
When a setup is installing an app, this setup should expect to have permission to write on Program Files. Once the setup is finished, Program Files should be writable only for other setups aiming to update binaries to other versions.
Please install executable files to the %programfiles% folder in Windows - a simple MSI based install package can perform an active setup for any new user who logs onto the machine to create the user specific files and folders in their profiles %appdata% folder. You see this behaviour for Internet Explorer, Adobe reader, etc. - It's the little MSI installer window that pops up the first time you log onto a machine which has those applications installed. - Thanks - a system admin :)
My opinion, for what it's worth, is that user-specific program files is just asking for trouble and is a damn stupid thing to do.
A much more sensible approach is to install different versions of your program to:
\Program Files\Your Program\Program_v0.1\Program.exe
\Program Files\Your Program\Program_v0.2\Program.exe
\Program Files\Your Program\Program_v0.3\Program.exe
\Program Files\Your Program\Program_v0.4\Program.exe
I would then place a bootstrapping launcher at:
\Program Files\Your Program\ProgramLauncher.exe
Then, the user application data folder will only contain data, including an INI/XML/Settings file that indicates the version of the program that this user is working with.
Such an approach satisfies the core tenant of keeping data and executing code separate, allows every user to run a specific version of the code, and offers a small amount of de-duplication by ensuring the same executable code is not copied multiple times across user folders.
Otherwise, go right ahead with installing programs to AppData and undoing the years it has taken us to achieve clean separation of code and data. I found this thread because I noticed that Chromium and DropBox are installing code to AppData. I'm going to uninstall those program, and change the permissions on my AppData folder to exclude execution to ensure I can easily spot other programs attempting the same BS.

What is the purpose of program files directory in windows?

I wonder about this because we are developing an application, after installation some files were copied to program files and some to user profile directory. But, we found some issues w.r.t program files. Now all files are installed in the current user's directory. Even Google Chrome, does so. What do you think?
If you install a given application on 10 different accounts, do you really want the application to exist 10 times on disk?
The program files directory is for just that, the executable files, dlls, assemblies and other executable code and non editable configuration data associated with a program. The user profile directory is for data and code associated with the individual user.
The program files directory in Windows is a place where all the installed files go.
But there are some customizations needed depending on users. Those go into user's directory.
Like Downloads folder, customization of Mozilla firefox, Winamp, etc.
There has to be different profiles for each user to customize the applications.
But the commonly needed files of a software need not be installed in each user account; hence they are installed in Program Files
Since Vista the Program Files directory has been marked as off limits so applications can't write to it by default unless given admin privileges.
This is for better security to stop other applications manipulating existing installed applications.
There is a good write up of this here on how to work with UAC but also learning to write more secure applications.
http://msdn.microsoft.com/en-au/magazine/cc163486.aspx

Resources