Wednesday, March 23, 2011

How to pass a (byte[] lpData) with integer value to RegSetValueExW P/Invoke

I have this P/Invoke RegSetValueExW that sets the value to the registry key. in C#

[DllImport("coredll.dll", EntryPoint = "RegSetValueExW")]
public static extern int RegSetValueExW(uint hKey, string lpValueName,
            uint lpReserved,
            uint lpType,
            byte[] lpData,
            uint lpcbData);

I'm having a problem with the 4th param byte[] lpdata. I need to pass a DWORD with a value of 5 (int) in it. Everything is OK if I pass a string (REG_SZ), just need to convert using the GetBytes function.

If I call GetBytes("5") it converts it to ascii value of 53 so it writes 53 on the registry value instead of 5

From stackoverflow
  • I've got to start by asking why you are using PInvoke here when there is already a method for setting registry values in the Microsoft.Win32.RegistryKey class? Or are you stuck using an old version of the Compact Framework?

    Assuming you have a good reason for the PInvoke, the easiest answer is just to overload the PInvoke declaration for integer values. i.e.:

    [DllImport("coredll.dll", EntryPoint = "RegSetValueExW")]
    public static extern int RegSetValueExW(uint hKey, string lpValueName,
            uint lpReserved,
            uint lpType,
            ref int lpData,
            uint lpcbData);
    
  • If you need to pass an integer value you can simply cast it to byte

    byte[] lpData = new byte[] { (byte)5 };
    
    Stu Mackellar : This is dangerous - it certainly won't work if the value is greater than 255.
    Stephen Martin : But integers are 4 bytes, why would you create a 1 byte array? Also, what happens if your integer value is 4935325? Also, why are you casting an int, 5, to int when you are creating a byte array?
    Stefano Driussi : err, sorry my mistake when i was writing. i meant to cast it to byte thanks. yes it's dangerous but it was the fastest way to it came to my mind.
    Roy Astro : thanks ste for the quick answer.
  • Use REG_DWORD instead of REG_SZ and then use BitConverter.GetBytes(Int32) to convert the int to a byte[].

  • Hi stephen. i am currently using Compact Framework 2.0. So there is no registry classes available

    Stephen Martin : I thought the registry classes were added in CF 2.0? Though it has been a long time since I did anything with Windows CE, so I could easily be wrong.
    Roy Astro : Hey Stephen you are right there is already a class for registry in CF2.0 its under Microsoft.Win32.Registry. Oh well. Thanks for your comment i wouldn't know if you did not mention it
  • Thanks Guys for the answers. I tried Ste answer and it worked but I guess the proper way to do it is Stephen's answer. Thanks again

0 comments:

Post a Comment