使用 C# 应用程序在 WinCE 中保存注册表值
-
09-06-2019 - |
题
我正在开发带有触摸屏的 WinCE 6.0 系统,该触摸屏将其校准数据(x-y 位置、偏移量等)存储在系统注册表(HKLM\HARDWARE OUCH)中。现在,我将 cal 值放入注册表项中,这些注册表项在构建时放入操作系统映像中。这对于我从中获取原始校准值的显示器来说效果很好,但是当我将此图像加载到具有不同显示器的另一个系统时,触摸屏指针位置(可以理解)关闭,因为两个显示器没有相同的校准值。
我的问题是,我不知道如何正确地将值存储到注册表中,以便它们在电源循环后仍然存在。看,我可以重新校准第二个系统上的屏幕,但新值仅存在于易失性存储器中。我向我的老板建议,我们可以告诉我们的客户,让设备始终保持电源状态,但效果并不理想。
我需要有关如何将新常量保存到注册表中的建议,以便我们可以在将显示器运送给客户之前校准一次显示器,而不必为我们构建的每个单元制作单独的操作系统映像。
已知可在 CE6.0 中运行的 C# 方法会很有帮助。谢谢。
-奥德巴斯塔
解决方案
我想您可能正在寻找的是RegistryKey 类的Flush 函数。这通常是不必要的(默认情况下注册表是延迟刷新的),但是如果在系统有机会执行此操作之前关闭设备的电源,则更改将被丢弃:
http://msdn.microsoft.com/en-us/library/microsoft.win32.registrykey.flush.aspx
此功能在 .NET Compact Framework 2.0 及更高版本中可用。
其他提示
关于这个问题的后续:
谢谢 DannySmurf,最终需要做的就是刷新注册表项。然而,在达到这个阶段之前,我还缺少一些步骤。所以,事情的真相是这样的:
- 我使用的是基于 RAM 的注册表,根据设计,注册表在冷启动后不会保留。我必须将注册表切换到基于配置单元的注册表。
当切换到基于 hive 的注册表结构时,您需要确保 hive 存在于非易失性介质上。这是在 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) 已加载。执行此操作的方法是在每个驱动程序初始化键周围添加以下格式的指令:
;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;
}