성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# - 파일 확장자에 연결된 프로그램을 등록하는 방법 (3) - "Open with" 목록에 등록 </h1> <p> 지난번에 .1myext 확장자에 연결 프로그램을 등록했는데요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# - 파일 확장자에 연결된 프로그램을 등록하는 방법 (1) - 기본 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/10966'>http://www.sysnet.pe.kr/2/0/10966</a> C# - 파일 확장자에 연결된 프로그램을 등록하는 방법 (2) - 웹 브라우저가 다운로드 후 자동 실행 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/10967'>http://www.sysnet.pe.kr/2/0/10967</a> </pre> <br /> 그런데, 사용자가 탐색기에서 특정 파일과 연결하고 싶어 마우스 우클릭 후 "Open with" / "Choose another app"을 선택해도 우리가 만든 예제 프로그램은 항목에 나오질 않습니다.<br /> <br /> 그 목록에 끼고 싶다면, "SOFTWARE\Classes\Applications" 경로에 command를 소유한 레지스트리 키를 하나 등록해 두어야 합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\SOFTWARE\Classes\Applications] [HKEY_CURRENT_USER\SOFTWARE\Classes\Applications\YourExt.exe] [HKEY_CURRENT_USER\SOFTWARE\Classes\Applications\YourExt.exe\shell] [HKEY_CURRENT_USER\SOFTWARE\Classes\Applications\YourExt.exe\shell\open] [HKEY_CURRENT_USER\SOFTWARE\Classes\Applications\YourExt.exe\shell\open\command] @="\"C:\\YourExt\\bin\\Debug\\YourExt.exe\" \"%1\"" </pre> <br /> 코드로 표현하면 대략 다음과 같은 정도의 변화만 있으면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > private static void ProcessFileExtReg(bool register) { using (RegistryKey classesKey = Registry.CurrentUser.OpenSubKey(@"Software\Classes", true)) { // ...[생략]... RegistApplication(classesKey, register); } } private static void RegistApplication(RegistryKey classesKey, bool register) { using (RegistryKey appKey = classesKey.<span style='color: blue; font-weight: bold'>OpenSubKey("Applications", true))</span> { if (register == true) { using (RegistryKey exeKey = appKey.<span style='color: blue; font-weight: bold'>CreateSubKey(assocExeFileName))</span> { RegistShellOpenCommand(exeKey); } } else { // ...[생략]... } } } private static void RegistShellOpenCommand(RegistryKey baseKey) { using (RegistryKey shellKey = baseKey.CreateSubKey("shell")) { using (RegistryKey openKey = shellKey.CreateSubKey("open")) { using (RegistryKey commandKey = openKey.CreateSubKey("command")) { string assocExePath = GetProcessPath(); string assocCommand = string.Format("\"{0}\" \"%1\"", assocExePath); <span style='color: blue; font-weight: bold'>commandKey.SetValue(null, assocCommand);</span> } } } } </pre> <br /> 변경된 등록 프로그램을 실행한 후, 탐색기에서 아무 파일이나 우클릭을 해 "Open with" / "Choose another app" 메뉴를 선택하면 다음과 같이 프로그램 항목이 보이는 것을 확인할 수 있습니다.<br /> <br /> <img alt='yourext_openwith_1.png' src='/SysWebRes/bbs/yourext_openwith_1.png' /><br /> <br /> 그런데, 이렇게 사용자가 "Open with"로 연결 프로그램을 바꾸면 어떤 변화가 있을까요?<br /> <br /> 아마도, 가장 쉬운 방법으로 그냥 해당 확장자의 연결 항목을 바꿔버리는 걸로 구현하는 것을 생각해 볼 수 있습니다. 즉, 다음과 같이 연결된 프로그램이 등록되었다면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\Classes\yourext.1myext.v1\shell\open\command] @="c:\path\to\yourext.exe \"%1\"" [HKEY_CURRENT_USER\Software\Classes\.1myext] @="yourext.1myext.v1" </pre> <br /> 이를 notepad.exe로 바꾼다면 다음과 같이 변경하면 그만입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\Classes\.1myext] <span style='color: blue; font-weight: bold'>@="txtfile"</span> </pre> <br /> 그런데, 마이크로소프트의 '탐색기' 개발자는 이런 방식을 취하지 않았습니다. 실제로, "test.1myext" 파일을 "Open with" 기능으로 연결 프로그램을 메모장으로 바꾸면 다음의 레지스트리 키가 생성되고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.1myext </pre> <br /> 그 하위에 "OpenWithList" 키를 통해 해당 확장자로 연결된 적이 있는 프로그램들의 "SOFTWARE\Classes\Applications\[...exe...]" 식별자가 등록됩니다. 가령, 방금 전에 ".1myext" 확장자를 "Open with"로 메모장과 연결했다면 다음과 같은 설정을 볼 수 있습니다.<br /> <br /> <img alt='yourext_openwith_2.png' src='/SysWebRes/bbs/yourext_openwith_2.png' /><br /> <br /> OpenWithList가 연결된 적이 있는 프로그램들의 목록을 보여준다면, 실제로 현재 사용자가 연결한 프로그램 설정은 "UserChoice"에 있습니다.<br /> <br /> <img alt='yourext_openwith_3.png' src='/SysWebRes/bbs/yourext_openwith_3.png' /><br /> <br /> "ProgId" 값이 "Applications\NOTEPAD.EXE"로 나오는데, 이는 "SOFTWARE\Classes\Applications\NOTEPAD.EXE" 항목을 의미합니다. 여기서 재미있는 것은 "Hash" 값입니다. 현재 "Dx/cvUgkjM8="로 되어 있는데 이는 "ProgId"의 유효성 검사에서 오는 듯 합니다. 즉, 외부에서 프로그래밍적인 방법을 이용해 임의로 이 값을 바꾸는 것이 허용되지 않습니다. 가령 제가 "ProgId" 값을 "Applications\test.exe"로 바꾸고 싶어도 Hash 값 생성 규칙을 알 수 없기 때문에 유효하지 않게 되는 것입니다. (참고로, 같은 NOTEPAD.EXE로 등록해도 다시 하면 Hash값이 바뀝니다.)<br /> <br /> 또 한가지 재미있는 점은, 연결 프로그램의 설정 값에 대한 우선 순위가 "Software\Classes\.1myext"보다 "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.1myext"의 것이 더 높다는 점입니다. 이 때문에 사용자가 설정한 값이 이후 설치되는 프로그램의 확장자 연결에 상관없이 독립적으로 유지가 가능합니다. 사용자 입장에서의 배려가 돋보이는 부분입니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 그렇다면, 자신의 프로그램으로 특정 확장자 연결을 강제로 설정하고 싶다면 어떻게 해야 할까요? 공식적인 방법은 없는 듯 하지만, 어쨌든 레지스트리 등록 정보를 기반으로 밀어버리는 것을 해볼 수 있습니다. 제 경우에 다음과 같은 레지스트리 값을 모두 새로운 프로그램으로 연결해 보았는데요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\UserChoice 삭제 HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Roaming\OpenWith\FileExts\.1myext 삭제 HKEY_CURRENT_USER\Software\Classes\.1myext 의 ProgId 교체 </pre> <br /> 위의 역할을 하는 프로그램을 첨부 파일의 ReplaceAssoc 프로젝트로 구현했습니다. 가령, ".1myext" 확장자를 교체하고 싶다면 다음과 같이 실행해 주면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > c:\temp>ReplaceAssoc .1myext </pre> <br /> 테스트 해보면 windows 8에서는 ".1myext" 확장자 교체는 잘 되었지만 알집과 연결된 ".zip"의 경우에는 뭔가 설정이 더 있어서 그런지 연결 프로그램이 해제된 상태로만 바뀌고 교체까지는 안되었습니다. 반면, 윈도우 10의 경우 모두 연결 프로그램이 잘 교체되었습니다. (물론, 비공식적인 방법이므로 향후 얼마든지 동작은 바뀔 수 있습니다.)<br /> <br /> (<a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1028&boardid=331301885'>첨부 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> </p><br /> <br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1041
(왼쪽의 숫자를 입력해야 합니다.)