views:

721

answers:

2

I have an old update program written in vb6, which runs as admin. However, because it runs as admin, all the files it downloads and saves are read-only to other users. Even files in public places like the shared application data folder (which is where I'm saving the files in question).

I'm lucky I found this before the 'vista-compatible' release. Vista hides the problem by redirecting non-admin writes and future reads to a sortof 'virtual' folder. But the next update may replace the file, and the non-admin program will still go to the virtual folder and use the old file.

As the admin user, how do I allow other users full control of files I write in vb6?

+1  A: 

It's not necessarily who writes the file, but where they write it to. The program files folder and it's sub folders are read-only to all standard users by default. Try using the All Users Application Data folder instead.

This is a little tricky for VB6, since it was not at all designed with Vista in mind. Some of the relevant folders were re-named and there's no way I know to get vb6 to give you the exact folder you want short of using a "Declare Function" alias to call directly into the windows API.

So the easiest reliable way I know to find a suitable location is to use the %ALLUSERSPROFILE% environment variable. That returns "C:\Documents and Settings\All Users" by default on XP and "C:\ProgramData" by default on Vista. From there you can look for an "Application Data" folder. It won't be there and you don't need it on Vista, but creating one if it doesn't exist won't hurt anything. That gives you a consistent folder structure on both systems from which you can create a sub folder for your app to use as a work space.

And one final note: this isn't a new change for Vista. Program Files folders have always been read-only to standard users by default. XP worked the same way. It's just that so many people run as administrators in XP you might be able to get away with it.

Joel Coehoorn
The files in question are in the application data folder for all users (C:\AppData on vista). The updater also modifies and registers the program files, which is it must run as admin.
Strilanc
Updates to programs shared by multiple users _should_ require admin rights. That's just common sense from a sysadmin perspective. It's odd, though, that non-program files aren't working for you from the App Data folder. Have you checked security options to see who has rights?
Joel Coehoorn
Any file created/replaced by the updater is read-only for standard users. But I want normal users to have full permissions for application data files so the program can function.
Strilanc
Karl Peterson has published `SysFolders`, a nice VB6 wrapper for the Windows API to help find these special folders. http://vb.mvps.org/samples/SysFolders
MarkJ
+2  A: 

The way I do this is to make it an Installer responsibility.

Use VSI 1.1 to create an Installer MSI for your application. Create an application data folder under CommonAppDataFolder.

As a post-build step run a script to perform the following:

  1. Set the MSI database for a per-machine installation: Property table, row with ALLUSERS set to 1.
  2. In the Directory table, locate the entry for CommonAppDataFolder and obtain its directory Index. Use this Index to query the Directory table for an entry where CommonAppDataFolder is the parent and obtain its Index (this is your app data subfolder).
  3. Look in the File table to obtain the component Index of your program.
  4. Create the CreateFolder table in the database if it isn't present. Add a row to CreateFolder for the desired application subdirectory by its Index, tying it to your program's component Index.
  5. Create the LockPermissions table if it isn't present. Insert a new LockPermissions row for your application data subdirectory, giving it FILE_ALL_ACCESS for Everyone.

That's about it.

You can do it this way, or use VSI 1.1 and then edit the MSI using Orca, or probably by using a 3rd party MSI authoring tool these entries will be settable via its GUI and can be saved in the Installer project. I just use a small WSH script I run after each VSI 1.1 build.

AFAIK this is the recommended way of accomplishing such things according to Windows application guidelines. If your needs are fancier you might use multiple subdirectories or sub-subdirectories some allowing full access, some read-only, etc.

Your program can locate the folder using Shell Automation objects or by calling Shell32 as a standard DLL (using Declare Function or a TLB).

Bob Riemersma
I see, so if I setup my program's data folder to allow normal access then the problem should be solved?
Strilanc
That's about it I would think. I'm not sure if there is any good brief code floating around for doing this from your VB6 program though.
Bob Riemersma