Save registry values in WinCE using a C# app

11,224

Solution 1

I think what you're probably looking for is the Flush function of the RegistryKey class. This is normally not necessary (the registry is lazily-flushed by default), but if the power is turned off on the device before the system has a chance to do this, changes will be discarded:

http://msdn.microsoft.com/en-us/library/microsoft.win32.registrykey.flush.aspx

This function is available in .NET Compact Framework version 2.0 and better.

Solution 2

Follow-up on this question:

Thanks DannySmurf, flushing the registry key was ultimately what needed to be done. However, there were a few steps that I was missing before reaching that stage. So, here's what came to light:

  • I was using a RAM-based registry, where by design the registry does not persist after a cold boot. I had to switch the registry to hive-based.
  • When switching to a hive-based registry structure, you need to make sure that the hive exists on a non-volatile medium. This is specified in the platform.reg file:

    [HKEY_LOCAL_MACHINE\init\BootVars]
    "SystemHive"="\\Hard Disk\\system.hv"
    "ProfileDir"="\\Documents and Settings"
    "RegistryFlags"=dword:1               ; Flush hive on every RegCloseKey call
    "SystemHiveInitialSize"=dword:19000   ; Initial size for hive-registry file 
    "Start DevMgr"=dword:1
    
  • Once the system.hv file is on the hard disk (CF card in my case), the values in the registry will persist after a cold boot. Note that the system.hv file contains all the HKLM keys.

  • It's also important to note that any drivers that need to be initialized on boot have to be specified as such in the .reg files of the solution. For example, I had to make sure that the hard disk drivers (PCMCIA) were loaded before trying to read the system hive file from them. The way to do this is to add a directive in the following format around each driver init key:

    ;HIVE BOOT SECTION
    [HKEY_LOCAL_MACHINE\Drivers\PCCARD\PCMCIA\TEMPLATE\PCMCIA]
      "Dll"="pcmcia.dll"
      "NoConfig"=dword:1
      "IClass"=multi_sz:"{6BEAB08A-8914-42fd-B33F-61968B9AAB32}=PCMCIA Card Services"
      "Flags"=dword:1000
    ;END HIVE BOOT SECTION
    

That, plus a lot of luck, is about it.

Share:
11,224
odbasta
Author by

odbasta

Updated on June 05, 2022

Comments

  • odbasta
    odbasta almost 2 years

    I'm working on a WinCE 6.0 system with a touchscreen that stores its calibration data (x-y location, offset, etc.) in the system registry (HKLM\HARDWARE\TOUCH). Right now, I'm placing the cal values into registry keys that get put into the OS image at build time. That works fine for the monitor that I get the original cal values from, but when I load this image into another system with a different monitor, the touchscreen pointer location is (understandably) off, because the two monitors do not have the same cal values.

    My problem is that I don't know how to properly store values into the registry so that they persist after a power cycle. See, I can recalibrate the screen on the second system, but the new values only exist in volatile memory. I suggested to my boss that we could just tell our customer to leave the power on the unit at all times -- that didn't go over well.

    I need advice on how to save the new constants into the registry, so that we can calibrate the monitors once before shipping them out to our customer, and not have to make separate OS images for each unit we build.

    A C# method that is known to work in CE6.0 would be helpful. Thanks.

    -Odbasta

  • ctacke
    ctacke over 12 years
    To clarify, it's incorrect to say a RAM-based registry doesn't persist by design. In fact there are HAL calls (technet.microsoft.com/en-us/query/aa447038) the OEM can specifically implement so that a RAM-based registry will persist. Hive-based registries didn't exist before CE 4.x, so that's how everyone persisted registries in the "old days".