Сохранение значений реестра в WinCE с помощью приложения C#

Я работаю над системой WinCE 6.0 с сенсорным экраном, который хранит данные калибровки (координаты x-y, смещение и т. д.) В системном реестре (HKLM \ HARDWARE \ TOUCH). Прямо сейчас я помещаю значения cal в разделы реестра, которые помещаются в образ ОС во время сборки. Это отлично работает для монитора, с которого я получаю исходные значения калибровки, но когда я загружаю это изображение в другую систему с другим монитором, положение указателя сенсорного экрана (по понятным причинам) выключено, потому что два монитора не имеют одинаковых значений калибровки .

Моя проблема в том, что я не знаю, как правильно сохранять значения в реестре, чтобы они сохранялись после отключения питания. Видите ли, я могу повторно откалибровать экран во второй системе, но новые значения существуют только в энергозависимой памяти. Я посоветовал своему боссу просто сказать нашему клиенту, чтобы он всегда оставлял питание на устройстве, но это не очень понравилось.

Мне нужен совет о том, как сохранить новые константы в реестре, чтобы мы могли один раз откалибровать мониторы, прежде чем отправлять их нашему клиенту, и не создавать отдельные образы ОС для каждого создаваемого нами модуля.

Был бы полезен метод C#, который, как известно, работает в CE6.0. Спасибо.

-Одбаста

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
11 062
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Я думаю, что вы, вероятно, ищете функцию 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
    

Вот и все, плюс большая удача.

Чтобы уточнить, было бы неверно говорить, что реестр на основе ОЗУ не сохраняется по дизайну. Фактически, существуют вызовы HAL (technet.microsoft.com/en-us/query/aa447038), которые OEM может специально реализовать, чтобы реестр на основе RAM сохранялся. Реестры на основе Hive не существовали до CE 4.x, поэтому в «старые времена» реестры сохранялись именно так.

ctacke 16.08.2011 05:56

Как я понял, вам нужно знать, как установить значение в реестр во время выполнения. Я надеюсь, что приведенные ниже коды могут вам помочь.

с использованием 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;
    }

Другие вопросы по теме