Solved

Reading the Registry from a (VB) COM dll

Posted on 2001-07-03
7
268 Views
Last Modified: 2008-02-01
I am tring to read the Registry from a COM dll and having some problems.

The idea is as follows...

When I want to read a user defined registry variable I put the following line of code in my vb com dll.
myvar = GetSetting(appname:="myappname", section:="mysection", key:="myvarname", Default:="failure")

This key is located in HKCU/software/VB and VBA program settings/myappname/mysection/....

The package the dll is loaded into runs under the user (Identity tab in Package properties) which has the registry key set.

This works for me most of the time - However, the read from the registry fails after a server reboot.  The actual read from GetSetting fails,  I don't even get the "Default" string.  At that stage I have to do all sorts of thigs to get it working again.
Deleting the package and re-setting up sometimes works.  But as you can imagine this is not really good enough.

Has anybody seen this problem before and can offer advice or a solution?

I dont want to have to resort to ini files or hard coded variables.  The registry is a good solution (when it works!)



PS I Hope my question is clear - I hate unclear questions!


0
Comment
Question by:Kennedy
7 Comments
 
LVL 3

Expert Comment

by:newjack
ID: 6248350

This is a tip I got from ASP-today about reading registry values in ASP (and this should work in VB as well)

Maybe this helps:

Tip of the Day!

        By Srinivasa Sivakumar
        ================================================================
        How to read registry from ASP?

        With the help of Windows Scripting objects, RegRead
        method we can read information from the registry.

        <%
        Set objShell = CreateObject("WScript.Shell")
        Response.Write ?Registry Value: ? & objShell.RegRead

("RegistryPath")
        %>

        The Registry path should be delimited by a back-slash (\).
        The registry name should begin with the root. The valid root
        names are;

        HKCU - HKEY_CURRENT_USER
        HKLM - HKEY_LOCAL_MACHINE
        HKCR - HKEY_CLASSES_ROOT

0
 
LVL 4

Expert Comment

by:epeele
ID: 6248367
listening and learning
0
 
LVL 26

Expert Comment

by:EDDYKT
ID: 6248651
You should not store any registry under HKCU. You should store in HKLM.

The reason the getsetting failed is when the machine is reboot and no user logged in, the HKCU doesn't exist.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 7

Accepted Solution

by:
John844 earned 100 total points
ID: 6248683
add this code to a module.  there is a sample usage line at the function definition.

'Registry Key Security Options...
Private Const READ_CONTROL = &H20000
Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_SET_VALUE = &H2
Private Const KEY_CREATE_SUB_KEY = &H4
Private Const KEY_ENUMERATE_SUB_KEYS = &H8
Private Const KEY_NOTIFY = &H10
Private Const KEY_CREATE_LINK = &H20
Private Const KEY_READ = KEY_QUERY_VALUE + KEY_ENUMERATE_SUB_KEYS + KEY_NOTIFY + READ_CONTROL
Private Const KEY_WRITE = KEY_SET_VALUE + KEY_CREATE_SUB_KEY + READ_CONTROL
Private Const KEY_EXECUTE = KEY_READ
Private Const KEY_ALL_ACCESS = KEY_QUERY_VALUE + KEY_SET_VALUE + _
                       KEY_CREATE_SUB_KEY + KEY_ENUMERATE_SUB_KEYS + _
                       KEY_NOTIFY + KEY_CREATE_LINK + READ_CONTROL
'Registry Return Values
Private Const REGISTRY_ERROR_SUCCESS = 0

'Registry Data Types...
Private Const REG_SZ = 1                         ' Unicode nul terminated string
Private Const REG_EXPAND_SZ = 2                  ' Unicode nul terminated string
Private Const REG_DWORD = 4                      ' 32-bit number

Private Const REG_OPTION_NON_VOLATILE = 0       ' Key is preserved when system is rebooted


Private Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Boolean
End Type

Private Declare Function RegOpenKeyEx Lib "advapi32" Alias "RegOpenKeyExA" _
 (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, _
  ByVal samDesired As Long, ByRef phkResult 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 lpData As String, ByRef lpcbData As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32" (ByVal hKey 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 Long, ByVal samDesired As Long, _
  ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, ByRef phkResult As Long, _
  ByRef lpdwDisposition As Long) As Long
Private Declare Function RegSetValueEx Lib "advapi32" Alias "RegSetValueExA" _
 (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, _
  ByVal dwType As Long, ByVal lpData As String, ByVal cbData As Long) As Long


' Reg Key ROOT Types...
Public Enum HKEYTypes
    HKEY_CLASSES_ROOT = &H80000000
    HKEY_CURRENT_USER = &H80000001
    HKEY_LOCAL_MACHINE = &H80000002
    HKEY_USERS = &H80000003
    HKEY_PERFORMANCE_DATA = &H80000004
End Enum


'-------------------------------------------------------------------------------------------------
'sample usage - Debug.Print RegistryGetKeyValue(HKEY_CLASSES_ROOT, "COMCTL.ListviewCtrl.1\CLSID", "")
'-------------------------------------------------------------------------------------------------
Public Function RegistryGetKeyValue(KeyRoot As HKEYTypes, KeyName As String, SubKeyRef As String) As String
    Dim i As Long                                           ' Loop Counter
    Dim rc As Long                                          ' Return Code
    Dim hKey As Long                                        ' Handle To An Open Registry Key
    Dim hDepth As Long                                      '
    Dim sKeyVal As String
    Dim lKeyValType As Long                                 ' Data Type Of A Registry Key
    Dim tmpVal As String                                    ' Tempory Storage For A Registry Key Value
    Dim KeyValSize As Long                                  ' Size Of Registry Key Variable
   
    ' Open RegKey Under KeyRoot {HKEY_LOCAL_MACHINE...}
    '------------------------------------------------------------
    rc = RegOpenKeyEx(KeyRoot, KeyName, 0, KEY_QUERY_VALUE, hKey) ' Open Registry Key
   
    If (rc <> REGISTRY_ERROR_SUCCESS) Then GoTo GetKeyError          ' Handle Error...
   
    tmpVal = String$(1024, 0)                             ' Allocate Variable Space
    KeyValSize = 1024                                       ' Mark Variable Size
   
    '------------------------------------------------------------
    ' Retrieve Registry Key Value...
    '------------------------------------------------------------
    rc = RegQueryValueEx(hKey, SubKeyRef, 0, _
                         lKeyValType, tmpVal, KeyValSize)    ' Get/Create Key Value
                       
    If (rc <> REGISTRY_ERROR_SUCCESS) Then GoTo GetKeyError          ' Handle Errors
     
    tmpVal = Left$(tmpVal, InStr(tmpVal, Chr(0)) - 1)

    '------------------------------------------------------------
    ' Determine Key Value Type For Conversion...
    '------------------------------------------------------------
    Select Case lKeyValType                                  ' Search Data Types...
    Case REG_SZ, REG_EXPAND_SZ                              ' String Registry Key Data Type
        sKeyVal = tmpVal                                     ' Copy String Value
    Case REG_DWORD                                          ' Double Word Registry Key Data Type
        For i = Len(tmpVal) To 1 Step -1                    ' Convert Each Bit
            sKeyVal = sKeyVal + Hex(Asc(Mid(tmpVal, i, 1)))   ' Build Value Char. By Char.
        Next
        sKeyVal = Format$("&h" + sKeyVal)                     ' Convert Double Word To String
    End Select
   
    RegistryGetKeyValue = sKeyVal                                   ' Return Value
    rc = RegCloseKey(hKey)                                  ' Close Registry Key
    Exit Function                                           ' Exit
   
GetKeyError:    ' Cleanup After An Error Has Occured...
    RegistryGetKeyValue = vbNullString                      ' Set Return Val To Empty String
    rc = RegCloseKey(hKey)                                  ' Close Registry Key
End Function
0
 

Author Comment

by:Kennedy
ID: 6249544
newjack,  
I am currently pursuing your suggestion,  need to test few reboots first.

EDDYKT,
Even if the server is not logged in, HKCU should be available if the dll is run under a particular account (In the identity tab of the components package)

John844,
You're suggestion looks really impressive :)
But, I don't want to resort to it unless I really need to...
0
 
LVL 7

Expert Comment

by:John844
ID: 6249698
eddykt is right about not using HKEY_CURRENT_USER.  when the machine reboots, there is no current user.  if you put the item into HKEY_LOCAL_MACHINE it is always accessable.  
0
 

Author Comment

by:Kennedy
ID: 6250011
This solution works well enough for me to use.  I will not use newJacks solution because it does not seem to work from an Active X dll (Works from a VB exe though?)  I'm probably missing something here...

EDDYKT you were actually correct HKCU does not seem to be available directly after a reboot, however my dll did pull the data from the appropiate place when the server was logged out which is why I argued my point.  Anyway MSDN backed up what you said...

Thanks everyone for your help...
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

I have helped a lot of people on EE with their coding sources and have enjoyed near about every minute of it. Sometimes it can get a little tedious but it is always a challenge and the one thing that I always say is:  The Exchange of information …
I was asked about the differences between classic ASP and ASP.NET, so let me put them down here, for reference: Let's make the introductions... Classic ASP was launched by Microsoft in 1998 and dynamically generate web pages upon user interact…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now