Сохраните значения реестра в WinCE с помощью приложения C#.
-
09-06-2019 - |
Вопрос
Я работаю над системой WinCE 6.0 с сенсорным экраном, которая хранит данные калибровки (положение x-y, смещение и т. д.) в системном реестре (HKLM\HARDWARE OUCH).Прямо сейчас я помещаю значения калибровки в ключи реестра, которые помещаются в образ ОС во время сборки.Это отлично работает для монитора, с которого я получаю исходные значения калибровки, но когда я загружаю это изображение в другую систему с другим монитором, местоположение указателя сенсорного экрана (по понятным причинам) отключается, потому что два монитора не имеют одинаковых значений калибровки. .
Моя проблема в том, что я не знаю, как правильно хранить значения в реестре, чтобы они сохранялись после выключения и включения питания.Видите ли, я могу откалибровать экран второй системы, но новые значения существуют только в энергозависимой памяти.Я предложил своему боссу просто сказать нашему клиенту, чтобы он всегда оставлял питание включенным, но это не понравилось.
Мне нужен совет, как сохранить новые константы в реестр, чтобы мы могли один раз откалибровать мониторы перед отправкой клиенту, а не создавать отдельные образы ОС для каждого строящегося устройства.
Будет полезен метод C#, который, как известно, работает в CE6.0.Спасибо.
-Одбаста
Решение
Я думаю, что вы, вероятно, ищете функцию Flush класса RegistryKey.Обычно в этом нет необходимости (по умолчанию реестр очищается лениво), но если питание устройства будет отключено до того, как система успеет это сделать, изменения будут отменены:
http://msdn.microsoft.com/en-us/library/microsoft.win32.registrykey.flush.aspx
Эта функция доступна в .NET Compact Framework версии 2.0 и выше.
Другие советы
Дальнейшие действия по этому вопросу:
Спасибо DannySmurf, в конечном итоге нужно было очистить ключ реестра.Однако было несколько шагов, которые я пропустил, прежде чем достиг этой стадии.Итак, вот что выяснилось:
- Я использовал реестр на базе ОЗУ, в котором реестр не сохраняется после холодной загрузки.Мне пришлось переключить реестр на куст.
При переходе на структуру реестра на основе куста необходимо убедиться, что куст существует на энергонезависимом носителе.Это указано в файле 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;
}