You need to add the manifest (resource) to your exe.
The manifest has an XML resource with content similar to the one below. TrustInfo is a key section that does not allow the use of VirtualStore.
This example builds Microsoft.Windows.Common-Controls, which allows you to use runtime themes. If you remove this from the manifest, you can still save the TrustInfo section.
Vista uses TrustInfo to decide that an application "knows" about UAC limitations and does not use VirtualStore for this application
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity type="win32" name="Delphi 7" version="7.1.0.0" processorArchitecture="*"/> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="*"/> </dependentAssembly> </dependency> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false"/> </requestedPrivileges> </security> </trustInfo> </assembly>
Here is a page with more details on how to create and use manifest files:
http://ruminatedrumblings.blogspot.com/2008/03/vista-uac-manifest.html
And the Microsoft page on the application manifest schema:
http://msdn.microsoft.com/en-us/library/bb756929.aspx
Of course, once you do this, you will no longer be able to write data to c: \ program files \ or other protected places with UAC enabled. That's why Microsoft created the virtual store in the first place. It is designed to store old applications that are expected to be able to write to those (now protected) locations.
You have several different options:
1: change file location
Move the tdb file to another location. This is ideal, but may require most code changes. For some suggestions, see the Question “ The Right Design Way Around UAC Restrictions for Windows . ” Microsoft's recommendation is to store data that the user did not name in the Application Data folder. I tried this, but it’s very difficult for users to find the data to move it to another computer. I moved all my user data, even if the user didn’t save the file on purpose, to the My Documents folder. So when they receive a new computer, they can simply move My Documents (and most most of them anyway), and all my application data will also be moved.
2: change the permissions for the file so that standard users can read / write the file. Either your installer can do this, or you can update it after the fact, but you will need to work as an administrator to make changes.
3: Make the application run as administrator. If you set the “requireAdministrator” runlevel as Sertac notes, you can write files, but then your users will receive an Elevation UAC prompt each time they launch your application.
Also note that if you update users who run and save data in a virtual store, there is nothing that automatically moves this data to a new location. When you add the manifest to the application, it will begin to see the files that are in the c: \ program * directory. You may need to search for files in virtual storage and copy them to a new location for the user. The following is an example. In my case, the license files were stored in the installation directory. After I updated my application, I needed to search for the old license files and move them to a new location:
procedure TResetMain.CopyVirtFiles(); var VirtLicDir: string; NewLicDir: string; FileOp: TSHFileOp; TempPath : array[0..MAX_PATH] of Char; begin SHGetFolderPath(Application.Handle, CSIDL_LOCAL_APPDATA, 0, 0, TempPath); VirtLicDir := TempPath + '\VirtualStore\Program Files\My Company\Licenses'; NewLicDir := GetMyConfigDir(); if NewLicDir <> '' then begin NewLicDir := IncludeTrailingPathDelimiter(NewLicDir) + 'User Licenses'; end;