Microsoft MVP성태의 닷넷 이야기
.NET Framework: 104. Win32Exception 클래스 소개 [링크 복사], [링크+제목 복사],
조회: 22380
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 


Win32Exception 클래스 소개


.NET으로 Win32 API를 interop으로 호출을 할 때, 실패를 하면 그 원인을 알아낼 수 없어서 답답하지요. .NET에서는 Exception 클래스에서 친절한 오류 메시지를 알아낼 수 있지만, Win32 API를 호출했을 때는 그렇지 않습니다.

예를 들어 아래와 같은 OpenProcessToken이라는 Win32 API를 이용할 때,

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool OpenProcessToken(IntPtr processHandle, int acc, out IntPtr pHandleToken);

IntPtr tokenHandle = IntPtr.Zero;
IntPtr processHandle = new IntPtr(-2);

bool result
    = OpenProcessToken(processHandle,
    (int)(0x0020 | 0x00020000 | 0x0008),
    out tokenHandle);

위의 결과는 result == false가 나옵니다. 이런 경우, 왜 실패했는지를 알고 싶다면 Win32 API에서 제공되는 "GetLastError" API를 이용하면 되는데, 이 부분은 .NET BCL의 Marshal 타입에서 정적 메서드로 제공되고 있습니다. 그래서, 다음과 같이 그 원인을 알아낼 수 있습니다.

int errorCode = Marshal.GetLastWin32Error();

위와 같은 상황에서는 errorCode == 6입니다. 그런데, 6이라는 숫자가 어떤 걸 의미할까요? Visual C++에서는 Watch 윈도우의 변수에 ", hr"이라고 치면 오류값이 나옵니다. 아니면, 명령행 창에서 "NET HELPMSG <errorcode>"와 같이 치면 6에 대한 에러 메시지가 "The handle is invalid."라는 것을 알 수 있습니다. (Visual Studio 2008의 경우, C:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\errlook.exe를 이용하는 것도 가능합니다.)

그렇다면, 코드로는 어떻게 알아낼 수 있을까요?

Visual C++에서는 FormatMessage Win32 API를 이용해서 오류 메시지를 얻어낼 수 있는데요. 인터넷 검색을 해보시면 아시겠지만, 코드가 그다지 깔끔하게 나오지는 않습니다. 기왕이면, .NET에서 제공되는 좀 더 매끄러운 방법을 찾아보는 것이 좋겠지요. ^^

제가 처음에 생각해 냈던 것은 아래와 같은 코드였습니다.

int hr = Marshal.GetHRForLastWin32Error();
Exception ex = Marshal.GetExceptionForHR(hr);
string errorMessage = ex.Message;

실제로 errorMessage == "The handle is invalid. (Exception from HRESULT: 0x80070006 (E_HANDLE))"라고 해서 만족할 만한 수준입니다. 나름 위의 방법도 답이 될 수도 있지만, 원래 Microsoft에서 제공되는 전용 타입이 있는 데 그것이 바로 "Win32Exception"입니다.

그래서, 최종적으로 다음과 같이 코딩을 할 수 있습니다.

int errorCode = Marshal.GetLastWin32Error();
Exception ex = new Win32Exception(errorCode);
string errorMessage = ex.Message; // "The handle is invalid."





[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 7/10/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 151  152  153  [154]  155  156  157  158  159  160  161  162  163  164  165  ...
NoWriterDateCnt.TitleFile(s)
1233정성태2/16/201234582.NET Framework: 302. supportedRuntime 옵션과 System.BadImageFormatException 예외 [5]
1232정성태2/9/201230493VC++: 57. 웹 브라우저에서 Flash만 빼고 다른 ActiveX를 차단할 수 있을까? [3]파일 다운로드1
1231정성태2/8/201239935VC++: 56. Win32 API 후킹 - Trampoline API Hooking [5]파일 다운로드1
1230정성태2/6/201225170개발 환경 구성: 140. 프로젝트 생성 시부터 "Enable the Visual Studio hosting process" 옵션을 끄는 방법
1229정성태2/4/201230374.NET Framework: 301. P/Invoke의 성능을 높이기 위해 C++/CLI가 선택되려면? [5]파일 다운로드1
1228정성태2/4/201279755.NET Framework: 300. C#으로 만드는 음성인식/TTS 프로그램 [47]파일 다운로드1
1227정성태2/3/201230623.NET Framework: 299. 해당 어셈블리가 Debug 빌드인지, Release 빌드인지 알아내는 방법파일 다운로드1
1226정성태1/28/201271769.NET Framework: 298. 홀 펀칭(Hole Punching)을 이용한 Private IP 간 통신 - C# [15]파일 다운로드3
1225정성태1/24/201227012.NET Framework: 297. 특정 EXE 파일의 실행을 Internet Explorer처럼 "Protected Mode"로 실행하는 방법 [1]파일 다운로드1
1224정성태1/21/201238547개발 환경 구성: 139. 아마존 EC2에 새로 추가된 "1년 무료 Windows 서버 인스턴스"가 있다는데, 직접 만들어 볼까요? ^^ [11]
1223정성태1/20/201228654.NET Framework: 296. 괜찮은 문자열 해시함수? - 두 번째 이야기 [1]파일 다운로드1
1222정성태1/18/201236304.NET Framework: 295. 괜찮은 문자열 해시 함수? [4]파일 다운로드1
1221정성태1/17/201225341오류 유형: 147. System.Runtime.InteropServices.COMException (0x80005000)
1220정성태1/15/201225607.NET Framework: 294. Master web.config 파일을 수정하려면?파일 다운로드1
1219정성태1/15/201227928.NET Framework: 293. Microsoft PowerPoint 슬라이드를 HTML 파일로 ".files" 폴더 없이 저장하는 방법 (C# 코드)파일 다운로드1
1218정성태1/15/201240914.NET Framework: 292. RSACryptoServiceProvider의 공개키와 개인키 구분 [1]파일 다운로드2
1217정성태1/14/201242695.NET Framework: 291. .NET에서 WAV, MP3 파일 재생하는 방법 [1]파일 다운로드1
1216정성태1/14/201231309오류 유형: 146. Microsoft Visual C++ 재배포 패키지 - 설치 로그 남기는 방법 [1]
1215정성태1/9/201228882제니퍼 .NET: 20. 제니퍼 닷넷 적용 사례 (3) - '닷넷'이 문제일까? '닷넷 개발자'가 문제일까? [6]
1214정성태1/3/201225545제니퍼 .NET: 19. 제니퍼 닷넷 설치/제거 방법 - IIS
1213정성태12/31/201125505.NET Framework: 290. WCF - 접속된 클라이언트의 IP 주소 알아내는 방법 - 두 번째 이야기
1212정성태12/31/201125600오류 유형: 145. The trust relationship between this workstation and the primary domain failed.
1211정성태12/31/201130381.NET Framework: 289. WindowsFormsHost를 사용하는 XBAP 응용 프로그램파일 다운로드1
1210정성태12/30/201149318.NET Framework: 288. FFmpeg.exe를 이용한 C# 동영상 인코더 예제 [9]파일 다운로드1
1209정성태12/29/201124016개발 환경 구성: 138. BizTalk 2006 설치 방법
1208정성태12/28/201147503.NET Framework: 287. Excel Sheet를 WinForm에서 사용하는 방법 [8]파일 다운로드2
... 151  152  153  [154]  155  156  157  158  159  160  161  162  163  164  165  ...