C# 앱을 사용하여 WinCE에 레지스트리 값 저장
-
09-06-2019 - |
문제
저는 시스템 레지스트리(HKLM\HARDWARE OUCH)에 보정 데이터(x-y 위치, 오프셋 등)를 저장하는 터치스크린이 있는 WinCE 6.0 시스템을 작업하고 있습니다.지금은 빌드 시 OS 이미지에 추가되는 레지스트리 키에 cal 값을 배치하고 있습니다.원래 교정 값을 가져온 모니터에서는 제대로 작동하지만 이 이미지를 다른 모니터가 있는 다른 시스템에 로드하면 두 모니터의 교정 값이 동일하지 않기 때문에 터치스크린 포인터 위치가 (당연히) 꺼져 있습니다. .
내 문제는 전원을 껐다 켠 후에도 값이 유지되도록 레지스트리에 값을 올바르게 저장하는 방법을 모른다는 것입니다.보세요, 두 번째 시스템에서 화면을 재보정할 수 있지만 새 값은 휘발성 메모리에만 존재합니다.나는 상사에게 고객에게 항상 장치의 전원을 켜 두라고 말할 수 있다고 제안했지만 잘 진행되지 않았습니다.
새 상수를 레지스트리에 저장하는 방법에 대한 조언이 필요합니다. 그러면 모니터를 고객에게 배송하기 전에 한 번만 교정할 수 있고 우리가 구축하는 각 장치에 대해 별도의 OS 이미지를 만들 필요가 없습니다.
CE6.0에서 작동하는 것으로 알려진 C# 방법이 도움이 될 것입니다.감사해요.
-오드바스타
해결책
아마도 여러분이 찾고 있는 것은 RegistryKey 클래스의 Flush 함수일 것입니다.이는 일반적으로 필요하지 않지만(레지스트리는 기본적으로 지연 플러시됨) 시스템이 이 작업을 수행하기 전에 장치의 전원이 꺼지면 변경 사항이 삭제됩니다.
http://msdn.microsoft.com/en-us/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)가 로드되었는지 확인해야 했습니다.이를 수행하는 방법은 각 드라이버 초기화 키 주위에 다음 형식의 지시문을 추가하는 것입니다.
;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;
}