Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Folder Virtualization in Windows Vista


:P
On this page:

So I may have been a little hasty yesterday when talking about restrictive file access rights in Windows Vista. As it turns out there’s a mechanism that’s supposed to be able to work around these issues and it’s called folder virtualization.

 

The issue is that if you install into Program Files and you run as a non-admin account you won’t have write access to the files in your install folder. This is obviously a common thing for many applications that store their configuration data there as well as data.

 

I personally have always preferred installing data in a central location instead of plastering files all over your hard-drive which is what DLL and directory hell are all about. Nothing cleaner than a single directory install, right? Well, Vista doesn’t like it at least if you plan to run with a non-admin account.

 

So earlier today when I tried this virtualization did not work and that’s why I was having so much trouble with getting permission errors. I mucked around with my security policy setting (with gpedit.msc) a bunch and it’s possible that I enabled that feature and it’s disabled by default. I don’t know maybe somebody can check.

 

What this feature does is this: It detects any write access to a file by a user that doesn’t have rights to write to this file. It then makes a copy of the file in the user’s virtual store and happily allows the user to write to the file in the virtualized directory where the user has full rights.

 

 

What you see in this image are all the files that the application wrote to and made changes to which were then virtualized in this directory. The original files stay in the Program Files install folder.

 

That’s an impressive piece of architecture if you think about it, and it’s going to solve some problems with applications not having enough rights. It’s also useful for applications that never played well with multiple users – when turned on you get automatic user data separation for free.

 

Kinda confusing though. So I’m running Html Help Builder and it uses an INI file for a number of configuration settings. So I write out the config settings by saving from the Config dialog but the data doesn’t go into the .ini file in the install directory but the one in the virtual store. So if you ever look at the file in Program Files you're not going to see the same setting that the user just wrote.

 

Now if I log in as Administrator in turn though I do have rights to read the file from the original directory and now when I save it saves to program files. If I change the permissions in the program files directory and allow the non-admin user access to write it’s going to the Program Files directory again and it’s potentially shared. Looks like if the file exists in both locations the private virtualized location is used.

 

Brrrr… cool, but it can get confusing. So if you do want to share files in a single path for all users you have to be specific about it and give the appropriate users rights. Same if you want to share files over the network, but I suppose in that case a directory off the root is probably a better place for shared data.

 

 

Also as I mentioned yesterday the problem with WinZip actually turned out to be a problem with the WinZip self extractor which has lost its original command line interface. Once I ran the old version 2.x the Html Help Builder update (which is live now BTW for those of you that use Html Help Builder) worked.

 

 

As to installation I had to switch to an Admin user to install the application. For some reason Vista would not allow me to elevate to an Administrator in the existing session so I had to switch to my admin account, install, then come back and run Html Help Builder. I’m happy to report that once installed Html Help Builder ran Ok including building the help file and doing .NET imports (which is always a little tricky in terms of security).

 

 

I’m making headway, but I’m still a long way from getting this all dialed right. I’m not sure what the proper approach is for application installation and locations. I’ve been browsing around some of the Microsoft documents and they tell you a lot about what happens but not a lot about recommended approaches. <shrug>.

Posted in Vista  Installation  

The Voices of Reason


 

Garbin
December 04, 2006

# re: Folder Virtualization in Windows Vista

saved from another headache... thanks Rick :)

Florence Durant
February 28, 2007

# re: Folder Virtualization in Windows Vista

Hi, Rick.

I have used your Web Connect product for several years. I have a lot of respect for your thoughts on things. I have run into a problem with my application that was built using VFP 8.0 in which I distribute certain .vcx files which are shared between the VFP apps that comprise the application so that I don't have to include them in each project that uses them. These .vcx files are stored with the app files in a subfolder of the Program Files directory.

Because of the underlying way in which VFP opens these files when a class is used, they are automatically being virtualized in Windows Vista even though NOTHING is being written to them. Obviously this will cause problems in deploying future updates to the program as the class libraries that have been virtualized will not be updated.
I want to be able to turn off virtualization for my application in Vista. I have tried including an external application manifest file with a requestedExecutionLevel of "asInvoker". This does not disable virtualization of the libraries even though the Microsoft documentation says that it will. I have also attempted to embed the application manifest into my VFP executable using the mt.exe tool that ships with Visual Studio 2005. This appears to complete successfully, but the resulting executable is no longer recognized as a VFP file.

Do you have any information that can help me get past this problem? I’m supposed to leave on a ski trip on Friday and I know I’ll enjoy it a lot more if I am past this problem. I suppose that I could just require that the application files for my application be installed outside any of the Windows folders for which virtualization occurs, but not allowing my application files to be installed under the Program Files folder just seems wrong. Thoughts?

Thanks.

Florence Durant

James Moore
March 10, 2007

# re: Folder Virtualization in Windows Vista

Rick,

I've been having a problem trying to get more than local folders to show up in Vista when using the VFP function GETDIR() or using BrowseForFolder method of the Shell object. Have you encountered this issue and if so, do you know of solution. The exact same code works as expected in Win2K and WinXP. I'm assuming the issue may be along the same lines you mentioned in this post or some type of permissions issue.

Thanks in advance for any light you might be able to shed on this issue. :-)

James

Rick Strahl
March 10, 2007

# re: Folder Virtualization in Windows Vista

James some of the defaults may have changed in the way the Windows file dialogs work. GetDir() doesn't have any options unfortunately, although with GetFile() you can specify a host of options of what's visible...

James Moore
March 11, 2007

# re: Folder Virtualization in Windows Vista

Hmm... but even using WSH oShell object the way I described still will not allow any mapped driver letters to be displayed for selection. See the following code... I would think this would work:

#define BIF_BROWSEFORCOMPUTER    0x1000
#define BIF_BROWSEFORPRINTER    0x2000
#define BIF_BROWSEINCLUDEFILES    0x4000
#define BIF_BROWSEINCLUDEURLS    0x80
#define BIF_DONTGOBELOWDOMAIN    0x2
#define BIF_EDITBOX                0x10
#define BIF_NEWDIALOGSTYLE        0x40
#define BIF_NONEWFOLDERBUTTON    0x200
#define BIF_NOTRANSLATETARGETS    0x400
#define BIF_RETURNFSANCESTORS    0x8
#define BIF_RETURNONLYFSDIRS    0x1
#define BIF_SHAREABLE            0x800
#define BIF_STATUSTEXT            0x4
#define BIF_UAHINT                0x100
#define BIF_USENEWUI            0x40
#define BIF_VALIDATE            0x20

local loShell,loFolder,lcFolder,lnFlags

declare integer GetActiveWindow in Win32API

lcFolder = ''
lnFlags = BIF_NEWDIALOGSTYLE + BIF_NONEWFOLDERBUTTON + BIF_UAHINT

loShell = CreateObject('Shell.Application')
loFolder = loShell.BrowseForFolder(GetActiveWindow(),'Please Select Network Folder',lnFlags)

if vartype(loFolder) = 'O'
    lcFolder = loFolder.Items.Item.Path
endif

release loShell
loShell = null
release loFolder
loFolder = null

return lcFolder


I really just want the user to select a folder, not a file. If I use GetFile(), is there a way to select just a folder?

Thanks for any insight into this issue you may have.

James

James Moore
March 13, 2007

# re: Folder Virtualization in Windows Vista

Hey Rick,

Last night, I was messing around with the directory selection dialog (both VFP flavor and Win32API flavor) and found out if I mapped a drive letter to a created network share (not the default network share such as \\SERVER\c$\Some Folder), that the mapped drive letter actually showed up in the dialog. YAHOO! Making some progress. So, as long as there is a Network share (which all of my network installations call for anyway), and you map a drive letter to that share or folder under that share, the mapped drive letter displays in the dialog. So, at least for me, this issue has been resolved. Threw me because I was testing orignally on a Windows XP machine where all the mapped drive letters that I created displayed no matter if I connected to the default share or not. When I tried the same thing in Vista, they would not show. Finally, decided to map a drive letter to an existing share on my network and the drive letter now displays in the dialog.

Hope this helps somebody else out there.

Thanks,

James

Rick Strahl
March 13, 2007

# re: Folder Virtualization in Windows Vista

James you have to be careful with that because if you're not an admin user you may definitely not have access to the c$ share. Or the network for that matter in some scenarios.

I think you can always make this work with the FileOpen dialog box which allows you to specify whether to display network shares, but it's more work to make that behave for directories...

James Moore
March 13, 2007

# re: Folder Virtualization in Windows Vista

Thanks for the advise, Rick. I normally don't connect to the default (c$) share. I was just doing this during testing instead of setting up a network share which would normally be the case (by the network admin). It was just a bone-headed move on my part and cost me a lot of time since the same behavior was not the case in WinXP. Thanks again. I've always had a great deal of respect for you and your contributions to the VFP and overall development community. Thanks a bunch and hope the next wave you catch is the best one yet! :-)

All the best!

James

Mark Harpenau
April 06, 2007

# re: Folder Virtualization in Windows Vista

OK, I give up, ...back to the topic of UAC... I market an app to the public and provide the ability for users while in the app to "check for updates" and download and install them from within the app. Similar to what Rick does with some of his apps, I'm guessing. There's many advantages to this, and I don't want to have to require users to re-download an installation setup.exe and run it each time they need an update. Vista seems to just be making life very difficult for developers for what I think is a small improvement in Windows security. I think users are just going to get so used to clicking on the "Allow" buttons, and what's to stop a malware app from doing it's damage during an installation when the user gives it permission? I just think this is all too much trouble and restrictive for what it gains in security IMO. So, I'm leaning towards keeping my application architecture, and simply changing the installation package to install to a new root folder called "Apps". When I do this, all my issues with virtualization folders and write privs go away. Everything works and is solid again. Sorry, that MS has pushed me to create another root folder, but I've got work to do, rather than fiddle with manifests, and figure out where to spread my files out over a user's directory structure. Also, I found that the Virtualization stuff is really risky and scary. I've run into some serious issues with an app seemingly running ok, but using the wrong (deleted) files. Just Virtualization alone makes me want to stay clear of the Program Files folder. Maybe this is just a paradigm and I'll think differently years from now, but it's just too much effort to deal with and for what? So my app can live in Program Files?

Rick Strahl
April 06, 2007

# re: Folder Virtualization in Windows Vista

Mark I'm going through the same pains as we speak. I'm going through Help Builder at the moment and trying to dot all the i's and cross all the t's and there's always one more thing happening. Basically what I'm doing is moving anything updateable out of Program Files which is realistically as it should have been done originally, but of course this app is old and dates back before the days of LUA.

Everything is workable with the exception of the auto-update mechanism. That I cannot make work in program files so currently I check for the ability to write files in the local app path, and if not prompt users to quit the app and run the app again by Run as Administrator. This is obviously nothing as smooth as an auto-update, but it it's not huge hassle either.

Mark Harpenau
April 06, 2007

# re: Folder Virtualization in Windows Vista

Thanks Rick. Maybe I should take another look and see about doing the same thing, as I would like to keep the app in the PFs folder. Can I ask, where have you decided to keep your updatable files? I need my app to be accessible and be using the same data for "all users", so the Users\ folder doesn't work for me. I'm surprised there's not an AllUsers folder.

Rick Strahl
April 06, 2007

# re: Folder Virtualization in Windows Vista

I don't have shared data so it doesn't matter. Users can create their own data files and they can choose where to put them. If it needs to be shared they can use a standard folder and add the appropriate permissions. There is also All Users which is sharable as well.

For updates - the updates have to go into Program Files (or wherever the app was installed) hence the message to require Admin Privileges.

Remember too that if you need to set permissions for a shared file location ANYWAY you might as well change thepermissions in your specifc Program files folder. You can even do that during setup by executing CACLS or other utility to set permissions. You could install your app and add a special folder to the app and add open permissions to that folder by adding the EveryOne or Authenticated Users group... that might allow working around all of this although this goes against the Windows guidelines. But screw that - if you have data you have to share you have data you need to share <s> - there are no two ways around it.

Ross Trusler
April 15, 2007

# re: Folder Virtualization in Windows Vista

Rick -

I just finished LUA certification of one of my own products tonight - I'm in the trenches with you!

To make your auto-update feature work better than telling the user to execute your app with 'runas', sequester the auto-update functionality in a COM object, which can allow on-demand elevation via the COM elevation moniker. The COM object will have write access to your binaries.

Info on the particulars of the COM object are here: http://developersoven.blogspot.com/2007/02/leveraging-vistas-uac-with-delphi-part_3659.html

If updating in your app can also be instigated by the user, put the shield on command widget so that the user knows they are going to be asked for elevation when you instantiate the COM object.

For the uninteractive update process, it should be made minimally interactive, at least to the degree that the user is told that you are about to lauch the auto-updating process, which may require authentication.

Good night, and good luck.

Ross

Ross Trusler
April 15, 2007

# re: Folder Virtualization in Windows Vista

Mark - I ran into the same problem as you.

My solution was to move shared data to a subdirectory of the location specified by the 'AppData' value in HKLM\...\Shell Folders. Typically, this resolves to C:\Documents and Settings\All Users\Application Data\ in XP, and C:\ProgramData\

Create your <AppName> subdir, and mark it writable by the Everyone account. For some finesse, put your shared-but-write-once in that directory, but make a separate directory for writable shared data e.g. ...\<AppName>\Shared

Now, if all files are present at install, just change the permissions on the files, not the directory, which is more security-conscious.

In any case, these are better approaches than opening up the directory permissions within your C:\Program Files\<AppName> directory or subdirectory. It makes it easier to prevent abuse of your binaries, and makes any network admins less jittery (their policies may allow limited user writing to the Machine's AppData but not Program Files).

Your alternative of creating a new C:\ root folder won't solve your problem - only the creating user or the Admin Group will have permission to write to that folder.

Rick Strahl
April 16, 2007

# re: Folder Virtualization in Windows Vista

Thanks for the insight and links Ross. I suppose another way would be to just install a COM+ component in the system context and then do anything you want through that <g>... Kind of a scary though but not difficult to do with an installer...

Shreenivas
April 16, 2007

# re: Folder Virtualization in Windows Vista

Hi Rick,
I have a problem with Virtualization. I have a file (config.ini) in c:\program files\app name\dat folder. I have to share this file with the other users ("standard" users). What are the ways to achieve this? I will install this application as admin but while running they are standard users.

Thanks,
Shreenivas

Trupti
April 18, 2007

# re: Folder Virtualization in Windows Vista

Hi Rick,

I have some queries regarding virtualization.There is utility secpol.msc in which they have given that user account control can be enabled or disabled.Problem am facing is if I install an application with Administrator then it installs in C:\Program Files but if am writing some files through my application then it writes to the virtual folder.I need to write program which enables or disables this virtualization so that when my installed application writes some files then it will write in installed path only and not in the virtual folder.

Can you help out for this?

Thanks,

Trupti

Arizona
May 02, 2007

# re: Folder Virtualization in Windows Vista

I think I may have found a loop-hole with the virtualization/security aspects of UAC. That is, if an installer is running (assuming it is running with the heuristically elevated access), it is able to create files and folders in the Program Files folder.

What I've experimentally determined is that I can create a sub-folder (within Program Files) with a specified DACL. That is, if I use the sample code from MSDN for CreateMyDACL (http://msdn2.microsoft.com/en-us/library/ms717798.aspx), then I can create a folder within Program Files that all authenticated users are able to read AND write to.

I'm thinking of using this, but it kinda worries me to use it in a production application.

I'm looking for feedback.

Rick Strahl
May 02, 2007

# re: Folder Virtualization in Windows Vista

That's by design really. The virtualization folder is only accessed if the regular access fails, so if you're running with elevated rights at some point you get the actual program files data. This can be problematic in some situations if you're switching user modes.

In fact I did that with Help Builder a while back - I ran with low permissions, then switched UAC off and all of a sudden all my configuration settings were not there anymore because it's reading from another location. That's been fixed since, but it's something to consider.

Yes you can use your installer to create a directory (anywhere pretty much) where common files can be stored, but this is not appropriate according to the Windows guidelines. If you do that you should use the Program Files Common folder or create a completely separate data folder somewhere.

Arizona
May 03, 2007

# re: Folder Virtualization in Windows Vista

Rick,

You are right, creating a folder within "Program Files" would be a violation of the guidelines.

On a somewhat related note, have you (or anyone else) figured out a way to determine if the path for a new file will be virtualized to the VirtualStore when UAC is turned on?

Thanx,
-Az

Ian Sanderson
May 03, 2007

# re: Folder Virtualization in Windows Vista

So, what seems to be the best place to store common data ?

Applications installed into the /Program Files/ folder but where to put common data such as a database or config information where all users will be reading/writing the same data.

using SHGetSpecialFolderPath to get CSIDL_COMMON_APPDATA kinda sounds like it ought to get me a common appdata folder but, for normal users, in vista that still gets virtualized. d'oh!

Additionally, if the application wanted to 'hide' something such as a license code, trial expiry information etc, where would this be stored so that all users are using the same license, trial counters ?

When microsoft made Vista did it not occur to them that different users of the same computer might actually need to co-operate and share data ??

Antun's Blog
May 18, 2007

# Antun&#8217;s Blog &raquo; Blog Archive &raquo; OpenLaszlo and Windows Vista


Antun's Blog
June 12, 2007

# Antun&#8217;s Blog &raquo; 2007 &raquo; April


Gary
July 02, 2007

# re: Folder Virtualization in Windows Vista

Wow this has been an extremely helpful page. Thanks everyone! Yeh it's funny that Microsoft has not made these suggestions clear, or at least easy to find...

oopdb
July 09, 2007

# re: Folder Virtualization in Windows Vista

Hi,

Florence wrote:

>not allowing my application files to be installed under the Program Files folder
> just seems wrong

If you are sure that you want to install your application into C:\Program Files\ProductName\...
and write into HKEY_LOCAL_MACHINE\Software\ProductName registry key
then you can do these two things:

a) provide a manifest file with your application where you mention level="asInvoker"

b) provide a manifest file with your installer (or a separate helper EXE) where you mention level="asInvoker". Then give your installer (or a separate helper EXE) the ability to grant the 'Users' group write access into the C:\Program Files\ProductName\ and into the HKEY_LOCAL_MACHINE\Software\ProductName registry key

To achieve b), prepare yourself to write some Win32 API code

Look into MSDN for the functions GetNamedSecurityInfo(), GetAce(),LookupAccountSid(),
SetEntriesInAcl() and SetNameSecurityInfo(). A nice tool with source code to get some inspiration from, is the AccessEnum tool

Binary here:
http://www.microsoft.com/technet/sysinternals/Security/AccessEnum.mspx

Source code
http://web.archive.org/web/20060427234047/http://www.sysinternals.com/Files/AccessEnumSource.zip

oopdb
July 09, 2007

# re: Folder Virtualization in Windows Vista

Instead of:
>provide a manifest file with your installer (or a separate helper EXE) where you mention level="asInvoker"

Please read

>provide a manifest file with your installer (or a separate helper EXE) where you mention level="requireAdministrator"

Sorry.

Kishore
July 20, 2007

# re: Folder Virtualization in Windows Vista

Hi Rick,
I have developed a windows application using C# on XP system and created an Installer.
If i install this application on XP systems everything was working file.
If i try to install this on Vista Business Edition, getting the permissions problem.

Probelm Description:
while installing the applicatoin on Vista i am creating a shared folder under My Documents. My Application has one feature called "File Uplaod". Once i click on "File Upload", if will save the file in Database and move the file into Shared Folder.

Here the problem occurs. The file is saving to database scuuessfully but it is not moving into Shared Folder. I was getting " Access to the path '\\systemname\Shared Folder\filename' is denied".

Could u plz give me the solution for this sharing problem.

Note:
1. I have given full permissions to the Shared folders
2. If i try to install the same in Vista Ultimate Edition it was working with out any problems.

Regards,
Kishore.

Himi
July 20, 2009

# re: Folder Virtualization in Windows Vista

Hi Rick

I'hv a BHO build in VC6(ATL/COM) which is used to create a toolbar button and on button click i called URLDownloadtofile for my specified folder in which the file should be downloaded it works fine on XP but with Vista api URLDownloadtofile not working.

I have set the Protectedmode off option and also login as administrator but still not working.


regards
Himi

F-E
February 12, 2010

# re: Folder Virtualization in Windows Vista

The same happens in win7
Thanks for the info.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024