C# 윈폼에 한글(HWP) ActiveX 컨트롤, 즉 HwpCtrl을 올려 놓고 Open으로 문서를 띄우면 "접근을 허용하시겠습니까?"라는 확인창이 매번 뜹니다. 웹 페이지나 외부 프로그램이 사용자 몰래 로컬 파일을 열지 못하게 막는 장치라서 존재 이유는 분명합니다. 문제는 사내 업무용 프로그램처럼 내가 만든 프로그램이 내 서식 파일을 여는 상황에서도 똑같이 묻는다는 점이에요. 양식 수십 개를 연속으로 채워 출력하는 프로그램이라면 사용자가 그때마다 버튼을 눌러 줘야 합니다.

한컴에서는 이 확인 절차를 대신 처리해 주는 "보안승인모듈"을 DLL 형태로 배포하고 있고, 사용법도 안내하고 있습니다. 다만 예제가 C++, VB, HTML 기준이라 C#에서 어떻게 붙이는지는 직접 맞춰 봐야 합니다. 아래는 C# 기준으로 정리한 순서입니다.

광고

준비할 것

먼저 한컴 개발자 자료실(원본 기준 주소: http://www.haansoft.com/hnc/swlab/tech/down_read.action)에서 보안승인모듈 예제 DLL을 받습니다. 받은 DLL은 프로젝트의 bin\debug 폴더, 즉 실행 파일이 만들어지는 위치에 복사해 두면 됩니다. DLL 파일 이름은 바꿔도 동작에는 문제가 없습니다. 이름을 바꿨다면 아래 코드에서 경로 문자열만 같이 고쳐 주세요.

동작 원리

흐름은 두 단계입니다. 첫째, HKEY_CURRENT_USER\Software\HNC\HwpCtrl\Modules 레지스트리 키 아래에 "모듈 이름 = DLL 전체 경로" 형태로 값을 하나 등록합니다. 둘째, 컨트롤의 RegisterModule을 호출해서 그 모듈 이름을 FilePathCheckDLL 용도로 쓰겠다고 알려 줍니다. 그러면 컨트롤이 파일을 열 때 사용자에게 묻는 대신 등록된 DLL에게 확인을 맡깁니다.

HKCU 아래라서 관리자 권한 없이도 쓸 수 있다는 점이 편합니다. 대신 사용자 계정마다 따로 등록되므로, PC 한 대를 여러 계정이 쓰는 환경이면 각 계정에서 프로그램이 한 번씩은 실행돼야 등록이 됩니다. 아래 코드는 값이 없을 때만 등록하도록 되어 있어서 매번 실행해도 부담이 없습니다.

샘플 코드

원본 예제 코드입니다.

const string HNCRoot = @"HKEY_Current_User\Software\HNC\HwpCtrl\Modules";

axHwpCtrl1.Clear();

string myProjectPath= Path.GetFullPath(".\\");

if (Microsoft.Win32.Registry.GetValue(HNCRoot, "FilePathCheckerModuleExample", "Not Exist").Equals("Not Exist"))
{
    Microsoft.Win32.Registry.SetValue(HNCRoot, "FilePathCheckerModuleExample", projectPath + "FilePathCheckerModuleExample.dll");
}

axHwpCtrl1.RegisterModule("FilePathCheckDLL", "FilePathCheckerModuleExample");

string filePath = "파일명.hwp";

axHwpCtrl1.Open(filePath);

주의: 위 코드는 myProjectPath로 변수를 선언해 놓고 SetValue에서는 projectPath를 쓰고 있어서 그대로 붙여 넣으면 컴파일 오류가 납니다. 변수 이름만 맞춘 수정본은 아래와 같습니다.

const string HNCRoot = @"HKEY_Current_User\Software\HNC\HwpCtrl\Modules";

axHwpCtrl1.Clear();

string myProjectPath = Path.GetFullPath(".\\");

if (Microsoft.Win32.Registry.GetValue(HNCRoot, "FilePathCheckerModuleExample", "Not Exist").Equals("Not Exist"))
{
    Microsoft.Win32.Registry.SetValue(HNCRoot, "FilePathCheckerModuleExample", myProjectPath + "FilePathCheckerModuleExample.dll");
}

axHwpCtrl1.RegisterModule("FilePathCheckDLL", "FilePathCheckerModuleExample");

string filePath = "파일명.hwp";

axHwpCtrl1.Open(filePath);

Path를 쓰려면 파일 위쪽에 using System.IO;가 있어야 합니다.

실제로 붙일 때 막히는 지점

Path.GetFullPath(".\\")는 실행 파일 위치가 아니라 현재 작업 디렉터리를 기준으로 경로를 만듭니다. 비주얼 스튜디오에서 F5로 돌리면 둘이 같아서 잘 되는데, 바로가기에서 "시작 위치"를 다르게 지정했거나 다른 프로그램이 이 exe를 실행하면 엉뚱한 폴더가 레지스트리에 들어갑니다. 배포용이라면 Application.StartupPath나 AppDomain.CurrentDomain.BaseDirectory처럼 실행 파일 기준 경로를 쓰는 편이 안전합니다.

또 하나는 한 번 잘못된 경로가 등록되면 "Not Exist" 비교 때문에 다시 덮어쓰지 않는다는 점입니다. 프로그램 폴더를 옮겼는데 확인창이 다시 뜬다면 레지스트리 편집기에서 해당 값을 지우거나, 아예 조건 없이 매번 SetValue로 현재 경로를 써 넣도록 바꾸는 방법이 있습니다.

비트 수도 확인해야 합니다. 한글 ActiveX 컨트롤이 32비트면 프로젝트 플랫폼도 x86으로 맞춰야 컨트롤 자체가 로드되고, 보안승인모듈 DLL도 같은 비트로 맞아야 합니다. "Any CPU"로 빌드해 64비트 PC에서 돌리다가 컨트롤 생성부터 실패하는 경우가 흔합니다.