Reading from a database located in the Program Files folder using ODBC - vb6

We have an application that stores its database files in a subfolder of the Program Files directory. These files are redirected to the VirtualStore in Vista and Windows 7. We represent data from the database using Microsoft DataReports (VB6). So far so good.
But we now want to use Crystal Reports XI to represent data from the database. Our idea is to NOT pass this data to CR from our program, but to have CR retreive it from the database using a a system DSN through ODBC. In this way we hope to present our users with more flexibility in designing their own reports. What we do want to ensure though is that these system DSNs are configured correctly when the user installs our program or when the program calls the Crystal Report.
Is there a smart way to do this using System variables for instance, instead of having to write a routine that checks for OS-version, whether UAC is enabled on the OS, whether the write restrictions on the Program Files folder have been lifted, etc and then adapts he System DSN to point to either the C:\Program Files\OurApp\Data folder, or the C:\Users\User\AppData\VirtualStore\Program Files\OurApp\Data folder?
Suggestions for an entirely different approach are welcome too!

New applications should have an application manifest that specifies requestedExecutionLevel. This declares your program "Vista aware" and bypasses attempts at virtualization.
During installation you should create a folder like [CommonAppData]\Company\App\Full and set security on this folder to allow Full Access by Everyone (or by Users). Put your database into this folder.
For an MDB you can drop the database right here. For a client/server database put a UDL file here. Also see Use Universal Data Link (.udl) Files.
ODBC and DSNs are pretty obsolete technologies.
Using the suggested approaches should work for almost anything but the oldest Win95 computer.

Is this an Access database? You haven't specified.
For an Access database, you don't need to point your DSN to a specific database when you install it. You can modify the connection string to point to different databases at runtime (details). For instance
Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\mydatabase.mdb;Uid=Admin;Pwd=;
Can you simply read the installation path at runtime (in VB6 it is App.Path) and then send a different connection string to Crystal Reports?

It seems that Virtual Store takes care of everything, so you can point the DSN blatantly at C:\Program Files\MyApp\Data\mydb.mdb even while the database has been relocated to the Virtual Store.

Current Version
You might want to detect the current-version of Windows the system is running.
This will in turn help You in determining the correct PATH.
How to find windows version, build and revision numbers??
Read the the Registry keys –
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\CurrentBuildNumber
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\CurrentVersion
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\EditionID
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\ProductId
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\BuildLabEx
The CurrentBuildNumber is your Windows Build Number. Then CurrentVersion value is your windows version i.e. the version of your windows 7, windows vista, windows xp, etc. EditionID and ProductId to know the windows-edition and product-id.
The key BuildLabEx contains build number and revision number.
For example, in the value 6001.17387.x86fre.vistasp1_gdr.070927-1921:
the first four digits stand for build number i.e. 6001 and
the next five digits stand for windows revision number i.e. 17387.
x86 tells you that you are running a 32-bit operating system.
You might also be interested in this:
How to detect true Windows version?
GoodLUCK!!

Related

Which versions of windows generate local crash dump files through its error reporting? Which do not?

I'm writing a Java class to pull the version # of Windows from the registry, and then using this number to determine whether or not I need to create registry values to create a local dump. If not I need to know where to look for the dump files. Which versions of windows already have this feature through Watson or anything else?
Thanks
Vista was the first OS to fully embrace the WER system. With that, several registry settings were made available to configure how Windows Error Reporting would work. The one(s) you're interested in are the "LocalDumps" keys. It's an easy task to write a utility program to set these flags including the target folder for the dump files.

Where can we find a config data in Windows

In Windows, what are the built-in options to store config data (any data) locally?
I see three categories at least:
Files (such as .txt, .ini, .xml etc)
ODBC
Registry
Anything else?
I want to know if there are any other options.
Let's say you installed a software and you want to know where it is referencing for its own config data, where can we look for?
FYI:
OS: Windows 7 64 bit English version.
That's pretty much your options, but I have to pull you up on number 2. ODBC is not a location in which you can store data; it's a technology by which you can access data. An application interacts with an ODBC driver and then that driver interacts with a data source. That data source will most often be a database of some sort but certainly not always. I think what you actually meant to say was "database", which may or may not be accessed via ODBC from an application.
Am not sure that, this is what you need.
Click Start, point to All Programs, and then click Accessories.
Right-click Command Prompt, and then click Run As Administrator or Start-> Run-> cmd.
Type bcdedit at the command prompt
please refer this link for more info: http://technet.microsoft.com/en-us/magazine/ff404185.aspx

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.

System DSN is not working in Remote Desktop Server(RDS) for all users

I am running a VB 6 application for a report. It prints well in local with System DSN. But when i put the .exe of the application in RDS , report is not printing for System DSN rather its printing for User DSN. For System DSN its showing- "Cannot open SQL server".
My Efforts-
1.
http://social.technet.microsoft.com/Forums/windowsserver/en-US/bb2ced17-9dd3-40e4-b5b6-dd773ee7001c/system-dsn-on-rds-server
I tried with creating a 32 bit DSN using [WindowsDir]\SysWOW64\odbcad32.exe, but wont work out for me.
2.http://www.tek-tips.com/viewthread.cfm?qid=341776 I tried to change the permission of the System DSN as logged in as Administer and to give full permission for the user using regedt32. But still the same error as "Cannot open SQL server".
But as soon i create User DSN, it works fine. Please help.
If this problem is due to "stale" incorrect virtualized System DSNs that have been created for one or more users then changing the real System DSN won't matter. Programs that run in legacy mode for these users will keep seeing their virtualized copies.
System DSNs are stored under:
HKEY_LOCAL_MACHINE\Software\Odbc\Odbc.ini\Odbc Data sources
... but virtualized entries end up under:
'HKEY_USERS\<User SID>_Classes\VirtualStore\Machine\Software\Odbc\Odbc.ini\Odbc Data sources
... according to Registry Virtualization.
So to clean the virtualized registry entries out (delete them) to unmask the real DSN could be a lot of registry fiddling. You might do this most easily by creating a script or small program that gets run once under each corrupted user ID.
Or just reformat the boot drive and reinstall Windows!
This is without even going into possible issues around WOW64 registry redirection, a different though similar problem. Why not just stop using creaky old clumsy ODBC? Are you really using it on purpose?
The ultimate fix (after cleaning up the machine) is probably:
Stop using DSNs at all. They've been deprecated for a long time which is why we have DSN-less connection strings. These are easy and safe to store in places such as INI files when hard-coded connections are not practical. We've also had UDL files for ages now.
Deal with the appcompat issues in your programs and then add manifests to them so that they run in "UAC aware" mode instead of legacy mode. This prevents such confusing and hard to fix mishaps.

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.

Resources