Link to home
Start Free TrialLog in
Avatar of jagoodie
jagoodie

asked on

Checking for MDAC and Memory Usage

I have this app that runs when an employee logs on, and inserts a string into a database (currently Access) and then when it closes (at shutdown) it updates the entry with the time out.  The problem is that all of the computers do not currently have Microsoft Data Access installed (MDAC_TYP).  Is their a way to check for this so that when the app loads, if MDAC is not installed it just closes itself and does not display the error message about not finding the driver?

Also, this app is taking up 5 meg of memory (according to NT), is there a way to minimize the resources used? The app is only about 18k in size.
Thanks!
(i can send you the code if you want, my email is jay@goodier.net)
Avatar of jagoodie
jagoodie

ASKER

Edited text of question.
As regards MDAC (this information applies to versions 2 and later; I am not sure about earlier versions)

If you are using ADO, you can check for an entry in the Registry
"HKEY_LOCAL_MACHINE\Software\Microsoft\DataAccess"

the value of the "Version" item will tell you which version of ADO (hence MDAC) is installed, if any.

You could put this check into you installation program (if you are using Wise or InstallShield) and install then MDAC if necessary.


Hope this helps,
Laurence
ASKER CERTIFIED SOLUTION
Avatar of TimCottee
TimCottee
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yes, the program runs untill the user logs off, it is the only way that I can have it do something when they log of. Any better ideas? I don't like using 5 meg.  It is not retreiving many records at all (the database is only 200k currently, and it does not keep the recordset for more than a few seconds.
do you think ADO/MDAC is using all that? (it is the only extra refrence i use in the app)
Yes, I would like your registry api, i would like to learn how to use the registry effectivly.
Thanks!
Registry API - function prototypes

Public Enum RegRegistryKey
    'Registry Constants
    HKEY_CLASSES_ROOT = &H80000000
    HKEY_CURRENT_USER = &H80000001
    HKEY_LOCAL_MACHINE = &H80000002
    HKEY_USERS = &H80000003
End Enum

Public Enum RegAccessRight
    'Registry Specific Access Rights
    KEY_QUERY_VALUE = &H1
    KEY_SET_VALUE = &H2
    KEY_CREATE_SUB_KEY = &H4
    KEY_ENUMERATE_SUB_KEYS = &H8
    KEY_NOTIFY = &H10
    KEY_CREATE_LINK = &H20
    KEY_ALL_ACCESS = &H3F
End Enum

Public Enum RegCreateOpenDisposition
    'Key creation/open disposition
    REG_CREATED_NEW_KEY = &H1
    REG_OPENED_EXISTING_KEY = &H2
End Enum

Public Enum RegOpenCreateOption
    'Open/Create Options
    REG_OPTION_NON_VOLATILE = 0&
    REG_OPTION_VOLATILE = &H1
End Enum

Public Enum RegSeverityCode
    'Define severity codes
    ERROR_SUCCESS = 0&
    ERROR_ACCESS_DENIED = 5
    ERROR_NO_MORE_ITEMS = 259
End Enum

Public Enum RegValueType
    'Predefined Value Types
    REG_NONE = (0)                         'No value type
    reg_sz = (1)                           'Unicode nul terminated string
    REG_EXPAND_SZ = (2)                    'Unicode nul terminated string w/enviornment var
    reg_binary = (3)                       'Free form binary
    reg_dword = (4)                        '32-bit number
    REG_DWORD_LITTLE_ENDIAN = (4)          '32-bit number (same as REG_DWORD)
    REG_DWORD_BIG_ENDIAN = (5)             '32-bit number
    REG_LINK = (6)                         'Symbolic Link (unicode)
    REG_MULTI_SZ = (7)                     'Multiple Unicode strings
    REG_RESOURCE_LIST = (8)                'Resource list in the resource map
    REG_FULL_RESOURCE_DESCRIPTOR = (9)     'Resource list in the hardware description
    REG_RESOURCE_REQUIREMENTS_LIST = (10)
End Enum

Public Enum RegAccessTypeMask
    'masks for the predefined standard access types
    STANDARD_RIGHTS_ALL = &H1F0000
    SPECIFIC_RIGHTS_ALL = &HFFFF
End Enum

'Registry Function Prototypes

Private Declare Function RegOpenKeyEx Lib "advapi32" Alias "RegOpenKeyExA" _
  (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, _
  ByVal samDesired As Long, phkResult As Long) As Long

Private Declare Function RegSetValueExLong Lib "advapi32.dll" Alias "RegSetValueExA" _
    (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, _
     ByVal dwType As Long, lpValue As Long, ByVal cbData As Long) As Long

Private Declare Function RegSetValueExString Lib "advapi32" Alias "RegSetValueExA" _
  (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, _
   ByVal dwType As Long, ByVal szData As String, ByVal cbData As Long) As Long
   
Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" _
(ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, _
ByVal dwType As Long, lpData As Any, ByVal cbData As Long) As Long
 

Private Declare Function RegCloseKey Lib "advapi32" (ByVal hKey As Long) As Long

Private Declare Function RegQueryValueEx Lib "advapi32" Alias "RegQueryValueExA" _
  (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, _
   ByRef lpType As Long, ByVal szData As String, ByRef lpcbData As Long) As Long

Private Declare Function RegQueryValueExLong Lib "advapi32" Alias "RegQueryValueExA" _
  (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, _
   ByRef lpType As Long, lngValue As Long, ByRef lpcbData As Long) As Long

Private Declare Function RegCreateKeyEx Lib "advapi32" Alias "RegCreateKeyExA" _
  (ByVal hKey As Long, ByVal lpSubKey As String, ByVal Reserved As Long, _
   ByVal lpClass As String, ByVal dwOptions As RegOpenCreateOption, ByVal samDesired As Long, _
   lpSecurityAttributes As udtSecurityStruct, phkResult As Long, _
   lpdwDisposition As Long) As Long

Private Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" _
  (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, _
   lpcbName As Long, ByVal lpReserved As Long, ByVal lpClass As String, _
   lpcbClass As Long, lpftLastWriteTime As udtFileTime) As Long

Private Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, ByVal lpReserved As Long, lpType As Long, lpData As Byte, lpcbData As Long) As Long

Private Declare Function RegDeleteKey Lib "advapi32.dll" Alias "RegDeleteKeyA" _
  (ByVal hKey As Long, ByVal lpSubKey As String) As Long

Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" _
  (ByVal hKey As Long, ByVal lpValueName As String) As Long
   
 Private Declare Function OSRegQueryValueEx Lib "advapi32" Alias "RegQueryValueExA" _
 (ByVal hKey As Long, ByVal lpszValueName As String, ByVal dwReserved As Long, _
 lpdwType As Long, lpbData As Any, cbData As Long) As Long
 
 Private Declare Function OSRegSetValueEx Lib "advapi32" Alias "RegSetValueExA" _
 (ByVal hKey As Long, ByVal lpszValueName As String, ByVal dwReserved As Long, _
 ByVal fdwType As Long, lpbData As Any, ByVal cbData As Long) As Long

'function returns empty string if MDAC not installed
'else returns the version as a string
private function MDACpresent as string
  dim lngResult as long
  dim lngKey as long
  dim strMDACVersion as string
  dim lngNumChars as long

  lngResult = OpenRegistryKeyEx(  HKEY_LOCAL_MACHINE,   "Software\MicroSoft\DataAccess", 0&, _
  key_all_access Xor key_create_links, lngKey)

  if( lngResult = 0) then 'key is present
     strMDACVersion = String(255, " ")
    lngResult = RegQueryKeyEx  (lngKey, "Version" , 0&, _
     SZ_DATA, strMDACVersion, lngNumChars)
    if( lngResult = 0) then
      MDACPresent = vbnullstring
    else
      MDACPresent = left$(strMDACVersion, lngNumChars)
    end if
   
    lngResult = RegCloseKeyEx( lngKey)
  else
    MDacPresent = vbnullstring
  end if
end function



As regards the memory usage, do you leave the ADO connection open all the way through your application; or you may be creating an implicit connection object if you use the connection string, instead of a connection object, as a parameter in the RecordSet.Open method