본문 바로가기
Works/C#

[.NET] Windows Registry 등록/삭제

by Vader87 2019. 9. 8.
반응형

Custom URI Scheme 를 테스트 하다가 Windows 에 Registry 를 자동으로 등록/삭제 하면 편하겠다는 생각이 들어 찾아보게 되었습니다. 

공식 문서를 찾아봅니다.

https://docs.microsoft.com/ko-kr/dotnet/api/microsoft.win32.registry?view=netframework-4.5

 

Registry Class (Microsoft.Win32)

Windows 레지스트리의 루트 키를 나타내는 개체와 키/값 쌍에 액세스하는 static 메서드를 제공합니다.Provides objects that represent the root keys in the Windows registry, and static methods to access key/value pairs.

docs.microsoft.com

Registry Class 는 Windows 레지스트리의 루트 키를 나타내는 RegistryKey 객체와 키/값 쌍에 엑세스 하는 static 메서드를 제공합니다.

위 설명 처럼 Registry 에는 7개의 루트 키 값이 있습니다. 각 키 값에 대한 간략한 설명과 문서 링크 입니다.

Key 값 설명
ClassesRoot 애플리케이션 값 저장 입니다. 사용자별 구분이 필요 없는 값은 여기에 저장하는 것이 좋을 것 같습니다.
CurrentConfig 사용자와 관련 없는 하드웨어 구성 정보 값 입니다.
CurrnetUser 사용자별 기본 설정값 저장 입니다. 사용자 구분이 필요한 값은 여기에 저장하는 것이 좋아 보입니다.
DynData 동적 레지스트리 데이터라고 설명되어 있으며 현재 사용되지 않는 API 라고 합니다.
LocalMachine 하드웨어, 소프트웨어 등 로컬 시스템 정보 값이 저장됩니다. 유사한 데이터가 있는 경우 규칙에 따라 CurrentUser 값을 우선 적용한다는 설명이 있습니다.
PerformanceData 성능 관련 데이터 값을 기록 합니다.
Users 컴퓨터 각 사용자에 대 한 분기를 포함한다고 합니다. 컴퓨터 계정 별 설정값을 저장할 경우에 사용되는 것으로 보입니다.

제가 사용하려는 값은 ClassesRoot 에 저장하는 것이 좋아보입니다. steam 도 해당 위치를 사용하고 있네요.

RegistryKey 에 대한 내용도 찾아 봅시다.

https://docs.microsoft.com/ko-kr/dotnet/api/microsoft.win32.registrykey?view=netframework-4.5

 

RegistryKey Class (Microsoft.Win32)

Windows 레지스트리의 키 수준 노드를 나타냅니다.Represents a key-level node in the Windows registry. 이 클래스는 레지스트리 캡슐화 클래스입니다.This class is a registry encapsulation.

docs.microsoft.com

RegistryKey 를 사용하면 등록, 삭제, 수정이 가능해 보입니다. 필요한 기능들에 대해 정리해 봅니다.

Method 설명
CreateSubKey(String) 새 하위 키를 만들거나 기존 하위키를 엽니다.
SetValue(String, Object) 레지스트리 키에서 이름/값 쌍의 값을 설정합니다.
OpenSubKey(String) 지정된 하위 키를 검색합니다.
DeleteSubKey(String) 지정된 하위키를 삭제합니다.
DeleteSubKeyTree(String) 선택적 예외 처리를 사용하여 하위 키와 자식 하위 키를 재귀적으로 삭제합니다.

코드를 작성하고 레지스트리 편집기 창을 열어 실제로 작동하는지 확인해 봅니다.

using Microsoft.Win32;
...
private void Register()
{
	try
	{
		RegistryKey dev = Registry.ClassesRoot.CreateSubKey(REGISTRY_KEY);
		using (RegistryKey shell = dev.CreateSubKey("shell"), open = shell.CreateSubKey("open"), command = open.CreateSubKey("command"))
		{
			dev.SetValue("URL Protocol", "");
			command.SetValue("", CLIENT_PATH);
		}
	}
	catch (Exception e)
	{
		Console.WriteLine(e.Message);
	}
}

private void Unregister()
{
	try
	{
		if (Registry.ClassesRoot.OpenSubKey(REGISTRY_KEY, true) != null)
			Registry.ClassesRoot.DeleteSubKeyTree(REGISTRY_KEY);
	}
	catch (Exception e)
	{
		Console.WriteLine(e.Message);
	}
}

액세스가 거부되었습니다. 찾아보니 "HKEY_CLASSES_ROOT" 는 관리자 권한이 아니면 키를 생성할 수 없다고 합니다.

관리자 권한을 부여해 봅시다.

프로젝트 > 속성 메뉴에서 보안 탭으로 이동 후  ClickOnce 보안 설정 사용을 선택합니다. 

그러면 솔루션 탐색기의 Properties 항목에 app.manifest 항목이 추가 됩니다.

app.manifest 를 열어 requestedExecutionLevel의 level 값을 asInvoker 에서 requireAdministrator 로 변경 합니다.

이때 Visual Studio 에서 관리자 권한을 획득한 상태가 아닌경우 획득을 위해 Visual Studio 가 재실행 되는 경우가 있습니다.

여기까지 진행하고 처음에 설정 했던 프로젝트 > 속성 메뉴에서 보안 탭으로 이동 후  ClickOnce 보안 설정 사용을 해제 합니다. (ClickOnce 보안설정은 기본권한 만 사용가능하기 때문에 체크 해제를 하지 않으면 권한 설정이 제대로 되지 않는다고 합니다. 출처 : C#관리자권한으로 실행시키는 방법.)

관리자 권한을 갖고 있는지 코드에서 확인하려면 다음과 같이 작성하면 됩니다.

using System.Security.Principal;
...
private bool IsAdministractor()
{
	WindowsIdentity identity = WindowsIdentity.GetCurrent();
	if (identity != null)
	{
		WindowsPrincipal principal = new WindowsPrincipal(identity);
		return principal.IsInRole(WindowsBuiltInRole.Administrator);
	}
	return false;
}

다시 실행 해 보니 등록과 삭제가 정상적으로 됩니다.

 

참고

개발 환경 : .NET Framework 4.5

반응형

'Works > C#' 카테고리의 다른 글

Covariance and Contravariance  (0) 2022.01.19
C# 암호화 변수  (0) 2020.09.23
[.NET] Java Bridge  (2) 2019.03.22
For vs Foreach  (0) 2018.12.04

댓글