2019/01/29

[C++] OS 버전 알아내기

프로그래밍 중 OS 버전을 확인해야 하는 상황이 있어 내용을 찾아보았다.
검색을통해서 GetVersion, GetVersionEx 함수를 이용하는 방법과 VerifyVersionInfo 또는 Version Helper functions 를 사용하는 방법 그리고 시스템 파일(Kernel32.dll)의 파일 정보(GetFileVersionInfo)를 읽어들이는 방법이 있었다.
GetVersion, GetVersionEx 의 경우는 호환성 문제로 MS에서도 이 함수보다 VerifyVersionInfo 또는 Version Helper functions 를 사용하기를 권장하고 있었다.
VerifyVersionInfo은 사용법이 복잡해서 귀찮고 오래된 윈도우에서 동작하지 않을 수 있을 것 같아 다른 방법을 찾아보았다.

간단하게 도스 명령 Ver를 실행하여 결과를 해석하는 방법을 사용하였다.
Ver 명령어는 윈도우의 버전을 보여주는 명령어다. SystemInfo 라는 명령어도 있지만 많은 데이터를 보여주다보니 실행시간 다소 길다.
Ver 명령은 오래전부터있던 명령어로 윈도우의 버전만 간단하게 보여준다.
https://en.wikipedia.org/wiki/Ver_(command)

Windows 10의 경우
C:\>ver

Microsoft Windows [Version 10.0.17763.253]

Windows 7의 경우
C:\>ver

Microsoft Windows [Version 6.1.7601]

도스 명령의 결과를 받아오기 위해 _popen 함수를 사용하였다.

//////////////////////////////////////////////////////////////////////////
// OS Version
FILE* file = nullptr;
char szOutput[300];

file = _popen("ver", "r");
if ( file != nullptr )
{
 fread(szOutput, 1, sizeof(szOutput), file);
 fclose(file);

 std::string strVer(szOutput);
 std::regex reVer("[0-9]+\\.[0-9]+\\.?(\\*|[0-9]+)\\.?([0-9]+)?");
 std::smatch m;
 if( regex_search(strVer, m, reVer) )
 {
  m_strWinVersion = CString(szOutput);
  m_strWinVerNumber = CString(m.str().c_str());

  int n1stDot = m_strWinVerNumber.Find(L".");
  int n2ndDot = m_strWinVerNumber.Find(L".", n1stDot + 1);
  int n3rdDot = m_strWinVerNumber.Find(L".", n2ndDot + 1);
  if ( n1stDot >= 0 && n2ndDot > n1stDot )
  {
   m_nWinVerMajor = _tstoi(m_strWinVerNumber.Left(n1stDot));
   m_nWinVerMinor = _tstoi(m_strWinVerNumber.Mid(n1stDot + 1, n2ndDot - n1stDot - 1));
   if ( n3rdDot == -1 && n2ndDot != -1 )
   {
    m_nWinVerBuild = _tstoi(m_strWinVerNumber.Mid(n2ndDot + 1));
   }
   else if ( n3rdDot > n2ndDot )
   {
    m_nWinVerBuild = _tstoi(m_strWinVerNumber.Mid(n2ndDot + 1, n3rdDot - n2ndDot - 1));
   }
  }
 }
}
// OS Version
//////////////////////////////////////////////////////////////////////////

2019/01/15

Windows Boot Manager 옮기기

여러 HDD를 사용하다가 없애야 하는 상황이 발생하였다.
운영체제가 설치된 HDD를 제외하고 다른 HDD를 제거하려 하였으나 부팅이 되지 않는 상황에 부딪쳤다.
확인을 해 보니 Window Boot Manager 가 C드라이브가 아닌 Z드라이브에 설치되어 있었다.

$ bcdedit

Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=Z:
:

Windows Boot Loader
-------------------
identifier              {current}
device                  partition=C:
:

C 드라이브를 제외한 모든 HDD를 제거하기위해 Windows Boot Manager 를 C 드라이브로 옮겨야 했다.
우선 bcdboot 프로그램으로 C드라이브에 Boot 파일을 생성하였다.

$ bcdboot C:\Windows /s C:
Boot files successfully created.

그리고 난 후 diskpart 프로그램을 이용하여 C 드라이브의 파티션을 활성화 해 주었다.

$ diskpart
DISKPART> select disk 0
DISKPART> select partition 1
DISKPART> active

그리고 나서 C 드라이브를 제외한 모든 드라이버를 제거하고 부팅에 성공을 하였다.
bcdedit를 이용하여 확인을 해보니 Window Boot Manager 가 C드라이브 옮겨졌다.

$ bcdedit

Windows Boot Manager
--------------------
identifier              {bootmgr}
device                  partition=C:
: