Click to See Complete Forum and Search --> : Using API RegQueryValueEx with DllImport to read data from Registry


shrahul
July 29th, 2005, 09:11 AM
Hello,

I'm trying to read registry value using the API functions RegOpenKeyEx and RegQueryValueEx along with DllImport in C#. The results show that code runs fine but I'm not getting the desired data. Its returns 0 instead of the data. I'm including the code that I'm using

//*** declarations in the class *****

public static readonly UIntPtr HkeyLocalMachine = (UIntPtr)0x80000002;

public const string lpSubKey = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";

public const int KEY_QUERY_VALUE = 0x1;
public const int REZ_SZ =0x00000002;

[DllImport("advapi32.dll",EntryPoint="RegOpenKeyEx")]
public static extern int RegOpenKeyEx_DllImport(UIntPtr hKey,string lpSubKey,uint ulOptions,int samDesired,out IntPtr phkResult);

[DllImport("advapi32.dll",EntryPoint="RegQueryValueEx")]
public static extern int RegQueryValueEx_DllImport(IntPtr hKey,string lpValueName,int lpReserved,out uint lpType, IntPtr lpData,out uint lpcbData);

//****** declared on load or click event ****

IntPtr hKeyVal;
uint lpType;
uint lpcbData;
IntPtr q=new IntPtr();

int valueRet=RegOpenKeyEx_DllImport(HkeyLocalMachine,lpSubKey,0,KEY_QUERY_VALUE,out hKeyVal);

valueRet=RegQueryValueEx_DllImport(hKeyVal,"ProcessorNameString",0,out lpType, q,out lpcbData);


Output when viewd using different variables :

lpType= returns 1 which signify a string value
q returns 0 *** this should return data but does not
lpcbData returns 48 signifying size of the data being returned.

The return values of the functions show 0 which means success

Any help or insight on "Why I'm unable to get the data" would be highly appreciated.

Thanks
Rahul Sharma

mehdi62b
July 29th, 2005, 04:06 PM
I can't get why you want to use those API functions while there are some classes for this task //using Microsoft.Win32;
RegistryKey rk = Registry.LocalMachine.OpenSubKey
("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
string result=rk.GetValue("ProcessorNameString").ToString();
Console.WriteLine(result);

shrahul
July 30th, 2005, 12:16 AM
Thanks a lot for the suggestion mehdi62b but as I'm working on an E-Learning Project I need to demonstrate reading of registry in C# by calling Win 32 API's using DllImport. My hands are tied in this respect. So any help with tha above code would be grately appreciated.

Thanks,
Rahul

mehdi62b
July 30th, 2005, 08:19 AM
when you need a pointer to a string you should use a StringBuilder object, //its Definition
public static extern int RegQueryValueEx_DllImport(IntPtr hKey,string lpValueName,int lpReserved,out uint lpType,StringBuilder sb,out uint lpcbData); //its size should be 100 for having a sufficent capacity for the buffer
StringBuilder sb=new StringBuilder(100);
int valueRet=RegOpenKeyEx_DllImport(HkeyLocalMachine,lpSubKey,0,KEY_QUERY_VALUE,out hKeyVal);
valueRet=RegQueryValueEx_DllImport(hKeyVal,"ProcessorNameString",0,out lpType,sb,out lpcbData);

shrahul
July 31st, 2005, 11:57 PM
Hi,

This is what is troubling me. If I use a StringBuilder object the value returned by the function is 234 which signifies more data is available. This is the case even if I initialize the StringBuilder with 1000.

Even this doesn't help!!!!

Any other suggestion please.

Regards,
Rahul.

shrahul
August 1st, 2005, 09:59 AM
Was finally able to resolve the issue.
Here is the corrected code.

public static readonly UIntPtr HkeyLocalMachine = (UIntPtr)0x80000002;
public static readonly UIntPtr HKEY_CURRENT_USER = (UIntPtr)0x80000001;

public const string lpSubKey = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";

public const long REG_OPTION_NON_VOLATILE = 0x00000000L;

public const int KEY_QUERY_VALUE = 0x1;
public const int REZ_SZ =0x00000002;
public const int KEY_ALL_ACCESS = 0x3F;

[DllImport("advapi32.dll",EntryPoint="RegOpenKeyEx")]
public static extern int RegOpenKeyEx_DllImport(UIntPtr hKey,string lpSubKey,uint ulOptions,int samDesired,out UIntPtr phkResult);

[DllImport("advapi32.dll",EntryPoint="RegQueryValueEx")]
public static extern int RegQueryValueEx_DllImport(UIntPtr hKey,string lpValueName,int lpReserved,out uint lpType,StringBuilder lpData,ref int lpcbData);

UIntPtr hKeyVal;
int valueRet;
uint lpType;

StringBuilder sb=new StringBuilder(100);
int lpcbData=sb.Capacity;

valueRet=RegOpenKeyEx_DllImport(HkeyLocalMachine,lpSubKey,0,KEY_QUERY_VALUE,out hKeyVal);

valueRet=RegQueryValueEx_DllImport(hKeyVal,"ProcessorNameString",0,out lpType,sb,ref lpcbData);

MessageBox.Show("data type : " + lpType.ToString(),"Value",MessageBoxButtons.OK);

MessageBox.Show("data size : " + lpcbData.ToString(),"Value",MessageBoxButtons.OK);

MessageBox.Show("data : " + sb.ToString(),"Value",MessageBoxButtons.OK);

The last parameter in the ReqQueryValueEx was to be Ref instead of out.