PDA

Click to See Complete Forum and Search --> : [RESOLVED] References and Components Folders


q582gmzhi
Sep 23rd, 2008, 02:11 PM
Hi,

I am about to release a small VB6 application.

In references and components, it uses:
Visual Basic For Applications (Win\System32 Folder)
Visual Basic Runtime Objects ... (Win\System32 Folder)
Visual Basic Objects and Proceedures (ProgramFiles\MS Visual studio\VB98 Folder)

MSComm32 (App.Path)

It also read and writes to 4 ini files placed in the app.path.

Is it OK to place all the references in the App.Path along with MSComm32 and the 4 ini files or is it best to keep them where they are?

The program is mainly going on XP PC's but may eventually go on Vista PC's.

Many Thanks in advance.

Daz.....

dilettante
Sep 23rd, 2008, 06:44 PM
VB6.olb (Visual Basic Objects and Procedures) is part of the VB6 development environment is should not be deployed.

The other VB6 runtime libraries should be deployed properly to System32.

MSComm32 is a commonly shared component and should be deployed to System32.


You installer should check for these items and only deploy them at all if they are not already present (or newer versions are to be deployed). Most packagers produce the proper "script" or database to drive the installation process and will do this.

Never, never deploy COM dependencies into App.Path because this will risk inadvertant self-registration when the program runs. This can have nasty side effects if your application is ever uninstalled.

If you have dependencies that are truly unique to your application (generally components that you have created yourself) they normally go into a subfolder beneath App.Path, or a shared usage folder that is "company" (i.e. you) unique.

If you have a Whizbang application, it normally should not go into:

C:\Program Files\WhizBang

You can do this, but it can make sharing of components among applications you create more difficult. It is much more standard to create a folder structure like:
C:\Program Files\WhizCorp
\Common
\WhizComm.OCX
\WhizHelper.DLL
\WhizBang.EXE
This makes it easy to have the user later install your WhizClean application that shares one or both components. If your installer technology properly "usage counts" these components uninstalling one application won't remove components still needed by the remaining applications.

Often instead of a "company" folder people will group related applications under a "suite" folder instead:
C:\Program Files
\WhizCorp WhizTools
\Common
\WhizComm.OCX
\WhizHelper.DLL
\WhizBang.EXE
\WhizClean.EXE
\WhizCorp Widgets
\Common
\WidgetCtls.OCX
\WidgEdit.EXE
\WidgFormatter.EXE
The point is to avoid having DLLs and OCXs "right next to" an EXE, and to have a common shared location for anything shared among applications that is unique to your product.

If you had components shared among several product suites then these might go into:

C:\Program Files\Common Files\WizCorp

The important factor in all of this is that COM libraries which are shared need to go into proper shared locations, mostly based on the scope of sharing. Because the MSComm32.OCX is so widely shared, it belongs in System32.

This helps reduce DLL Hell for everyone.


INI files are never supposed to go into App.Path. The exception would be INI files that are installed once and then never altered or replaced. These rules have been in place since around 2000, and Vista now enforces them.

Instead these files should be installed into a subfolder your installer creates under "CommonAppData" which varies by OS and individual system, so you want to use SHGetFolderPath in Shell32.dll or similar to locate them.

Once again you create a "\company\product" folder structure underneath that folder, and may have to set permissions on it to permit the access your users will need.

Per-user settings normally go into a similar subfolder structure beneath "AppData" or "LocalAppData" (the latter being a non-roaming per-user location for settings and data).


People think of those as "Vista rules" because Windows did not enforce them until Vista. Almost all of the "never" or "always" comments I made above have exceptions as well.

Most of this is covered in various Deployment or Vista-specific FAQs on this site, as well as many Microsoft documents on Windows Guidelines, Deployment, and Vista UAC Changes.

q582gmzhi
Sep 24th, 2008, 07:39 AM
Hi Dilettante,

Thank you for a very in depth response, I am sure it will help me and other users who where thinking about which folders to use for References and Componenets.

Daz.....

q582gmzhi
Sep 24th, 2008, 07:54 AM
Hi again,

On start-up my program starts by checking the presence of the ini files in the App.Path etc, if they are present it resumes loadings, if not it then creates the ini's then continues to load.

Regarding Vista.

I assume their must be a way for the form onload to check what OS version the current PC has installed i.e: XP or Vista?

If the program then started and checked which OS was installed, then it could then decide whether to recreate the ini files in the 'CommonAppData' (Vista) or App.Path (XP) as you mentioned above?

Is this possible or is there more to it, i.e: would it mean two different versions one for XP and one for Vista to handle the Vista folder issue?

Regards

Daz.......

si_the_geek
Sep 24th, 2008, 08:56 AM
You should always use AppData and CommonAppData for data/config files in Windows 2000 and later - that has been in the developer guidelines that shipped with VB6 back in 1998 (but unfortunately hidden away, and just a "you must ..." rather than an example of how).

Vista adds extra problems (virtualisation etc), but Windows 2000 and XP can also have problems with data files in the application path (especially with PCs on a company network).

q582gmzhi
Sep 24th, 2008, 01:53 PM
Hi,

I am now at the point where I can detect OS verions, 95, 98 XP, 2000, Vista etc.

I can also return info using SHGetSpecialFolderPath and CSIDL values.

The ini files do not need to have restricted access, all users can use the software and must have the ability to re-create ini files, read, write and overwrite files access.

Which CSIDL's would you suggest to use with XP and Vista and or other OS, i.e: CSIDL_APPData, CSDIL_COMMON_APPDA etc etc?

Thanks in advance

Daz......

dilettante
Sep 24th, 2008, 05:32 PM
Same places for all OSs, from Win95 with the IE 4.x "shell update" on up. Places as derived via CSIDL values anyway. This hasn't changed until Vista where a new non-CSIDL scheme is available (SHGetKnownFolderPath Function (http://msdn.microsoft.com/en-us/library/bb762188(VS.85).aspx)), but the old one still works.

Thus OS-detection is almost never necessary, and as Microsoft recommends "test for the features you need, not the OS level."

The special folder to use depends on your purpose. Some values are per-user while others are per-machine, some are relatively hidden and meant for internal application use while others are meant for user-touchable things like documents.

A few:

CSIDL_APPDATA for per-user hidden roaming application data.
CSIDL_LOCAL_APPDATA for per-user hidden non-roaming application data.
CSIDL_COMMON_APPDATA for per-machine hidden application data.
CSIDL_PERSONAL for per-user user-touchable general documents storage.
CSIDL_COMMON_DOCUMENTS for per-machine user-touchable general documents storage.
CSIDL_MYPICTURES for per-user user-touchable images.

"User-touchable" means the user should be able to navigate there using Explorer and drag, drop, double-click on, delete, etc.


Things like INI files should go into a folder beneath CSIDL_COMMON_APPDATA if they are common to all users... unless you want users to hand-edit them. In that case they belong in a subfolder under CSIDL_COMMON_DOCUMENTS.

If each user has his own copy of an INI file then you'd put it in the appropriate per-user location instead.

Note that the "common" folders usually have security set so that only the owner has anything but read rights. Usually the creating user is the owner. This may mean your installer will have to set other security attributes on the subfolder tree it creates in such common locations to allow all users full or at least read/write and delete access to folders and files created there.

q582gmzhi
Sep 25th, 2008, 01:05 AM
Hi,

So If I understand this correctly, the installed OS 'knows' that CSIDL_COMMON_DOCUMENTS for example refers to different folders depending on the OS?

For example: CSIDL_COMMON_DOCUMENTS on an XP OS will bring up a common shared folder: C:\Documents and Settings\All Users\Documents

Whilst using CSIDL_COMMON_DOCUMENTS command on Vista OS will bring a common shared folder: C:\Users\Public\Documents

Having looked at the list CSIDL_PERSONAL may be the answer because if another user logs onto the PC, they will only have read rights on the files in CSIDL_COMMON_DOCUMENTS.

The software OnLoad first checks for the existence if the INI files, using CSIDL_PERSONAL path, it will not matter who logs on and off under different names if the files are absent it will create a new set, hopefully using logged on CSIDL_PERSONAL folder.

Thanks

Darrell........

si_the_geek
Sep 25th, 2008, 04:23 AM
So If I understand this correctly, the installed OS 'knows' that CSIDL_COMMON_DOCUMENTS for example refers to different folders depending on the OS?Yes, as that is the entire point of those constants and the API functions like SHGetSpecialFolderPath - programs (probably including Explorer/MyComputer) can use them to find out where the special folders are, simply by specifying which folder they want (the CSIDL constants). As the API functions are all part of Windows, they can be set up differently for each version of Windows if needed, but from our side they are always the same - they take known input(s) and give the expected output based on it.

On my computer is an odd setup in terms of the documents folders, I have actually moved them to another drive (to make backups easier), and the majority of programs find them without problem... but some programs (typically lower quality ones) still use the default path on the C drive. If I write code myself using SHGetSpecialFolderPath, it detects the correct locations.

q582gmzhi
Sep 25th, 2008, 05:24 AM
Thank for the confirmation much appreiciated.

One last thing, if I wanted a folder for example:

CSIDL_PERSONAL\MyApplicationFilesFolder

Using SHGetSpecialFolderPath, if the 'MyApplicationFilesFolder' folder does not exist within the 'CSIDL_PERSONAL folder' can I get the SHGetSpecialFolderPath to create it?

Or do I have to check if the folder exists then use something like MkDir?

Daz.....

si_the_geek
Sep 25th, 2008, 05:53 AM
SHGetSpecialFolderPath etc do not do anything with sub-folders, they simply return the path to the special folder itself.

You will need to check/create the folder yourself (Dir and MkDir should be fine, as should the alternatives).

dilettante
Sep 25th, 2008, 08:28 AM
Actually there is some help here. SHGetFolderPathAndSubDir() will return the special folder plus subdir and even create it if missing (given the right parameters).

I use variations on VB6 - AppEx Class, Assists Vista Programming (http://www.vbforums.com/showthread.php?t=499148&highlight=appex) in my programs, cutting out what I don't need and adding other things as I find the need. You can just add the AppEx.cls module from that demo project into projects of your own. This Class module automatically creates a global AppEx intance named AppEx in your program, so you don't even need to instantiate it in order to use it.

The special folder constants listed there have comments that may be a bit obsolete, taken from pre-Vista sources. As you noted even the default paths for these special folders have changed in Vista.

q582gmzhi
Sep 25th, 2008, 12:56 PM
Hi,

Thanks i will have a look and see how I get on with it.

Thanks

Daz.......

q582gmzhi
Oct 1st, 2008, 03:54 AM
Thanks for the advise, managed to get this working.

Daz......