使用C#应用程序在WinCE中保存注册表值

时间:2020-03-05 18:51:49  来源:igfitidea点击:

我正在使用带触摸屏的WinCE 6.0系统,该触摸屏将其校准数据(x-y位置,偏移量等)存储在系统注册表(HKLM \ HARDWARE \ TOUCH)中。现在,我将校准值放入注册表项中,这些注册表项会在构建时放入OS映像中。这对于我从中获得原始校准值的显示器来说效果很好,但是当我将此图像加载到具有不同显示器的另一个系统中时,触摸屏指针位置(可以理解)处于关闭状态(因为这两个显示器没有相同的校准值) 。

我的问题是我不知道如何将值正确存储到注册表中,以便它们在重启后仍然存在。可以,我可以在第二个系统上重新校准屏幕,但是新值仅存在于易失性存储器中。我向老板建议,我们只能告诉我们的客户,始终让设备保持电源状态-效果不佳。

我需要有关如何将新常量保存到注册表中的建议,以便我们可以在将监视器交付给客户之前进行一次校准,而不必为所构建的每个单元制作单独的OS映像。

已知可以在CE6.0中工作的Cmethod会有所帮助。谢谢。

-奥德巴斯塔

解决方案

回答

我认为我们可能正在寻找的是RegistryKey类的Flush函数。通常这不是必需的(默认情况下注册表会被延迟刷新),但是如果在系统有机会执行此操作之前关闭设备的电源,则更改将被放弃:

http://msdn.microsoft.com/zh-CN/library/microsoft.win32.registrykey.flush.aspx

.NET Compact Framework 2.0版及更高版本中提供了此功能。

回答

有关此问题的后续行动:

感谢DannySmurf,最终需要刷新注册表项。但是,在达到那个阶段之前,我缺少一些步骤。因此,以下是发现的内容:

  • 我使用的是基于RAM的注册表,根据设计,注册表在冷启动后不会持久存在。我不得不将注册表切换为基于蜂巢的注册表。
  • 切换到基于配置单元的注册表结构时,我们需要确保配置单元位于非易失性介质上。这是在platform.reg文件中指定的:
[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
  • 将system.hv文件放在硬盘上(在我的情况下为CF卡)上后,冷启动后注册表中的值将继续存在。请注意,system.hv文件包含所有HKLM密钥。
  • 同样重要的是要注意,必须在解决方案的.reg文件中指定所有需要在启动时初始化的驱动程序。例如,在尝试从中读取系统配置单元文件之前,我必须确保已加载硬盘驱动器(PCMCIA)。这样做的方法是在每个驱动程序init键周围添加以下格式的指令:
;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

那,加上很多运气就是这个。

回答

据我了解,我们需要知道如何在运行时为注册表设置值。我希望下面的代码可以为我们提供帮助。

使用Microsoft.Win32;

/// <summary>
    /// store a key value in registry. if it don't exist it will be created. 
    /// </summary>
    /// <param name="mainKey">the main key of key path</param>
    /// <param name="subKey">the path below the main key</param>
    /// <param name="keyName">the key name</param>
    /// <param name="value">the value to be stored</param>
    public static void SetRegistry(int mainKey, String subKey, String keyName, object value)
    {
        if (mainKey != CURRENT_USER && mainKey != LOCAL_MACHINE)
        {
            throw new ArgumentOutOfRangeException("mainKey", "\'mainKey\' argument can only be AppUtils.CURRENT_USER or AppUtils.LOCAL_MACHINE values");
        }

        if (subKey == null)
        {
            throw new ArgumentNullException("subKey", "\'subKey\' argument cannot be null");
        }

        if (keyName == null)
        {
            throw new ArgumentNullException("keyName", "\'keyName\' argument cannot be null");
        }

        const Boolean WRITABLE = true;
        RegistryKey key = null;

        if (mainKey == CURRENT_USER)
        {
            key = Registry.CurrentUser.OpenSubKey(subKey, WRITABLE);

            if (key == null)
            {
                key = Registry.CurrentUser.CreateSubKey(subKey);
            }
        }
        else if (mainKey == LOCAL_MACHINE)
        {
            key = Registry.LocalMachine.OpenSubKey(subKey, WRITABLE);

            if (key == null)
            {
                key = Registry.LocalMachine.CreateSubKey(subKey);
            }
        }

        key.SetValue(keyName, value);

    }

    /// <summary>
    /// find a key value in registry. if it don't exist the default value will be returned.
    /// </summary>
    /// <param name="mainKey">the main key of key path</param>
    /// <param name="subKey">the path below the main key</param>
    /// <param name="keyName">the key name</param>
    /// <param name="defaultValue">the value to be stored</param>

    public static object GetRegistry(int mainKey, String subKey, String keyName, object defaultValue)
    {
        if (mainKey != CURRENT_USER && mainKey != LOCAL_MACHINE)
        {
            throw new ArgumentOutOfRangeException("mainKey", "\'mainKey\' argument can only be AppUtils.CURRENT_USER or AppUtils.LOCAL_MACHINE values");
        }

        if (subKey == null)
        {
            throw new ArgumentNullException("subKey", "\'subKey\' argument cannot be null");
        }

        if (keyName == null)
        {
            throw new ArgumentNullException("keyName", "\'keyName\' argument cannot be null");
        }

        RegistryKey key = Registry.CurrentUser.OpenSubKey(subKey);

        if (mainKey == CURRENT_USER)
        {
            key = Registry.CurrentUser.OpenSubKey(subKey);
        }
        else if (mainKey == LOCAL_MACHINE)
        {
            key = Registry.LocalMachine.OpenSubKey(subKey);
        }

        object result = defaultValue;

        if (key != null)
        {
            result = key.GetValue(keyName, defaultValue);
        }

        return result;
    }