I am having a problem with Registry access.
Using the same code (an include file), I can create and recall keys Just fine in one program, but I cannot read those keys in another program
Here are the functions I am using to read and write. (All debug code is left in)
Both programs are run using the PB IDE "Compiler and Execute" in the same editing session.
The first program is a pure test program... it can add keys and read them back, or report errors doing so.
The second program...a "real" appplication is (so far) only trying to read the keys I created in the first program, so I can put the defaults on the screen for editing. However, in this second program, 'RegOpenKeyEx' in the GetUserSetting function always returns 2 (ERR_FILE_NOT_FOUND)
Regedit can find and modify the keys, values, etc. just fine, and the first program can read them back immeditately after they have been changed by refedit.
I have tried KEY_ALL_ACCESS instead of KEY_READ in the "Get" function, but the same results.
I also used RegEdit to delete the whole set of keys, then recompile both programs and start over.
When reading, both programs do the same thing: they call the GetUserSetting function with a key number.
Can anyone spot what I am doing wrong here? Need more info?
(I'm on Win/XP SP2)
Thanks,
MCM
Using the same code (an include file), I can create and recall keys Just fine in one program, but I cannot read those keys in another program
Here are the functions I am using to read and write. (All debug code is left in)
Code:
' READ FUNCTION FUNCTION GetUserSetting (BYVAL hWnd AS LONG, BYVAL Keyno AS LONG, szValue AS ASCIIZ, OPTIONAL szSubKey AS ASCIIZ) AS LONG LOCAL HomeKey AS LONG, szAppKey AS ASCIIZ * %MAX_PATH, sam AS LONG, hKey AS LONG, iret AS LONG LOCAL szValueName AS ASCIIZ * %MAX_PATH, iValueType AS LONG, cbValue AS LONG LOCAL pL AS LONG PTR, iGv AS LONG LOCAL fv AS LONG LOCAL E AS LONG fv = %TRUE ' default to failure szValue = "" ' default to no data HomeKey = %REG_HOMEKEY szAppkey = $REG_APPKEY sam = %KEY_ALL_ACCESS sam = %KEY_READ hKey = %NULL ' ----------------------------------------------------- ' if a subkey was specified, append that to the appkey '------------------------------------------------------ IF ISTRUE VARPTR(szSubKey) THEN szAppkey = szAppKey & "\" & szSubKey END IF ' get a handle to the key of interest iRet = RegOpenKeyEx (HomeKey, szAppkey, BYVAL %NULL, sam, hKey) E = iRet ' returns error code directly here MSGBOX USING$("RegOpenKeyEx FOR Key (Home #) # appkey '&' returns # with hKey # ", Homekey, KeyNo, szAppKey,iRet, hKey) IF iRet = %ERROR_SUCCESS THEN 'hresult key is valid and we can proceed to get the value szValueName = AppGetValueName (KeyNo) cbvalue = %MAX_PATH -1 'because they all are ' I could call this function with CBValue and szValue = NULL and that will ' return ERROR_SUCCESS f key is found along with the actual size and type. ' I like that and once this is working I will change this to do that. igv = RegQueryValueEx (hkey, szValueName, BYVAL %NULL, iValueType, BYVAL VARPTR(szValue), cbvalue) E = igv ' regqueryvalueEx returns the error value! don't use GetLastError() here! IF igv = %ERROR_SUCCESS THEN ' the value was found, an we may have to convert a integer to a string MSGBOX USING$("RegQUeryValueEx for '&' succeeded, returns iValueType #", szValueName, iValueType),, "KEY NO " & FORMAT$(Keyno) SELECT CASE AS LONG iValueType CASE %REG_DWORD pL = VARPTR (szValue) szValue = FORMAT$(@pl) END SELECT ' if the only other type we support (REG_SZ), szValue already contains the string data fv = 0& ' key successfully obtained ELSE szValue = "" ' if key not found returns igv=2 the sstem cannot find the file specified.. ' which is what it should do when the key is not found. Maybe I should ' return an explicit value for "Not found" here? ' I think I will have to, since it's possible to have key with no value MSGBOX USING$("ReqQueryValueEx Failed with igv # LE # ", igv,E) & SystemErrorMessageText(E) END IF RegCloseKey hKey ' regardless what happened if we got here the key was opened and must be closed ELSE 'Fails if not found, correctly. MSGBOX "RegOpenKeyEx failed " & SystemErrorMessageText (E) END IF FUNCTION = fv END FUNCTION ' WRITE FUNCTION FUNCTION SaveUserSetting (BYVAL hWnd AS LONG, BYVAL KeyNo AS LONG, szValue AS ASCIIZ, OPTIONAL szSubKey AS ASCIIZ) AS LONG LOCAL HomeKey AS LONG, szAppKey AS ASCIIZ * %MAX_PATH, sam AS LONG, hKey AS LONG, iret AS LONG LOCAL szValueName AS ASCIIZ * %MAX_PATH, iValueType AS LONG, cbData AS LONG LOCAL pL AS LONG PTR, iGv AS LONG LOCAL fv AS LONG LOCAL dwDisp AS DWORD ' will tell us if key was created new or opened old LOCAL dwOptions AS DWORD LOCAL dwData AS DWORD ' address of data LOCAL L AS LONG LOCAL w AS STRING ' for debugging only. fv = %TRUE ' default to failure HomeKey = %REG_HOMEKEY szAppkey = $REG_APPKEY sam = %KEY_ALL_ACCESS hKey = %NULL ' ----------------------------------------------------- ' if a subkey was specified, append that to the appkey '------------------------------------------------------ IF ISTRUE VARPTR(szSubKEy) THEN szAppkey = szAppKey & "\" & szSubKey END IF ' get a handle to the key of interest, so we can set it. ' here we are going to use RegCreateKey so if the key does not (yet) exist, it will be created dwOptions = %REG_OPTION_NON_VOLATILE iRet = RegCreateKeyEx (HomeKey, szAppkey, BYVAL %NULL, _ BYVAL %NULL, dwOptions, sam, _ BYVAL %NULL, hKey, dwDisp) IF iRet = %ERROR_SUCCESS THEN ' was created or opened IF dwDisp = %REG_CREATED_NEW_KEY THEN w = USING$("Created New Key '&'", szAppKey) ELSEIF dwDisp = %REG_OPENED_EXISTING_KEY THEN w = USING$("Opened Existing Key '&'", szAppkey) END IF ' MSGBOX W,,"SaveUserSetting Debugging" ' get the value name for this key szValueName = AppGetValueName (KeyNo) ' get the value type for this key iValueType = AppGetValueType (Keyno) IF iValueType = %REG_DWORD THEN L = VAL(szValue) dwData = VARPTR(L) cbdata = SIZEOF(L) ELSE ' must be REG_SZ dwData = VARPTR (szValue) cbData = LstrLen(szValue) + 1& 'include terminating null in size END IF igv = RegSetValueEx (hKey, szValueName, BYVAL %NULL, iValueType, BYVAL dwData, cbData) IF igv = %ERROR_SUCCESS THEN fv = 0& ' success! END IF RegCloseKey hKey END IF ' DECLARE FUNCTION RegSetValueEx LIB "ADVAPI32.DLL" ALIAS "RegSetValueExA" ' (BYVAL hKey AS DWORD, lpValueName AS ASCIIZ, BYVAL dwReserved AS DWORD, ' BYVAL dwType AS DWORD, lpData AS ANY, BYVAL cbData AS DWORD) AS LONG FUNCTION = FV END FUNCTION
Both programs are run using the PB IDE "Compiler and Execute" in the same editing session.
The first program is a pure test program... it can add keys and read them back, or report errors doing so.
The second program...a "real" appplication is (so far) only trying to read the keys I created in the first program, so I can put the defaults on the screen for editing. However, in this second program, 'RegOpenKeyEx' in the GetUserSetting function always returns 2 (ERR_FILE_NOT_FOUND)
Regedit can find and modify the keys, values, etc. just fine, and the first program can read them back immeditately after they have been changed by refedit.
I have tried KEY_ALL_ACCESS instead of KEY_READ in the "Get" function, but the same results.
I also used RegEdit to delete the whole set of keys, then recompile both programs and start over.
When reading, both programs do the same thing: they call the GetUserSetting function with a key number.
Can anyone spot what I am doing wrong here? Need more info?
(I'm on Win/XP SP2)
Thanks,
MCM
Comment