본문 바로가기

Programing/닷넷

[C#] 환경변수 - 시스템폴더

C:\Windows\system32

<

Console.WriteLine(Environment.SystemDirectory);

Console.WriteLine(Environment.GetFolderPath(Environment.SpecialFolder.System));


시스템 경로를 찾는 두 방법은 위와 같다.


1) 위의 방법은 정적 클래스인 Environment의 정적함수 SystemDirectory 를 이용하는 방법이다.

이 메소드는 아래와 같이 구현되어 있다.

public static class Environment

{

public const int MAX_PATH = 260;

public static string SystemDirectory 

{

get

{

        StringBuilder sb = new StringBuilder(MAX_PATH);

        if (Win32Native.GetSystemDirectory(sb, MAX_PATH) == 0)

        {

            __Error.WinIOError();

        }

        string path = sb.ToString();

        new FileIOPermission(FileIOPermissionAccess.PathDiscovery, path).Demand();

        return path;


}

}

}


다시 말하면 Native API, Win32 함수를 사용한다.

UINT WINAPI GetSystemDirectory(

  _Out_  LPTSTR lpBuffer,

  _In_   UINT uSize

);


2) 다른 방법은 System.Environment.SpecialFolder.System을 이용하는 방법이다.

열거형 SpecialFolder에는 아래와 같이 System이라는 값이 있다.

public enum SpecialFolder

{

System = 37,

}

이 값이 37이 된 이유는 CSIDL(링크)라는 것을 알면 이해가 된다. CSIDL_SYSTEM에 대응되는 값이다.

하지만 CSIDL은 현재 deprecated되었고 대신 KNOWNFOLDERID를 사용하라고 한다. 이 상수에 대응하면 FOLDERID_System라는 값이 된다.


마찬가지로 위에서 언급한 정적클래스 Environment의 GetFolderPath(Environment.SpecialFolder folder)를 이용하면 된다.

이 메소드는 아래와 같이 구현되어 있다.

public static class Environment

{

public const int MAX_PATH = 260;

public static string GetFolderPath(Environment.SpecialFolder folder)

{

if (!Enum.IsDefined(typeof(SpecialFolder), folder))

{

throw new ArgumentException(string.Format(

CultureInfo.CurrentCulture, GetResourceString("Arg_EnumIllegalVal"), new object[] { (int) folder }));

}

StringBuilder lpszPath = new StringBuilder(MAX_PATH);

Win32Native.SHGetFolderPath(IntPtr.Zero, (int) folder, IntPtr.Zero, 0, lpszPath);

string path = lpszPath.ToString();

new FileIOPermission(FileIOPermissionAccess.PathDiscovery, path).Demand();

return path;

}

}


내부적으로는 Win32의 SHGetFolderPath를 이용함을 알 수 있다.

HRESULT SHGetFolderPath(

  _In_   HWND hwndOwner,

  _In_   int nFolder,

  _In_   HANDLE hToken,

  _In_   DWORD dwFlags,

  _Out_  LPTSTR pszPath

);


처음에는 두 방법이 동일하다고 생각을 했지만 Windows API 수준으로 내려가 보면 다르다는 것을 알 수 있다.

GetSystemDirectory 함수는 Kernel32.dll에 구현되어 있고 SHGetFolderPath의 경우 Shell32.dll에 구현되어 있는 쉘 API이다.