Microsoft MVP성태의 닷넷 이야기
.NET Framework: 682. 아웃룩 사용자를 위한 중국어 스팸 필터 Add-in [링크 복사], [링크+제목 복사],
조회: 12828
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 
(연관된 글이 3개 있습니다.)

아웃룩 사용자를 위한 중국어 스팸 필터 Add-in

최근 들어 중국어 스팸 메일이 부쩍 늘었습니다. 아웃룩의 "Junk Email Options" / "International" / "Blocked Encoding List..." 기능을 이용해 중국어 문자(Chinese Simplified, Chinese Traditional)를 블록시켰지만 통하지 않았습니다. 검색해 보니, 해당 기능은 유니코드 인코딩된 메일에 대해서는 유효하지 않다고! ^^;

도메인명 기준으로 스팸 처리하는 것도 슬슬 귀찮아집니다. 왜냐하면, 심지어 .org에서도 스팸이 오는 등 꽤나 다양한 도메인에서 오기 때문입니다. 그런데, 의외인 것은 검색을 해도 아웃룩에 대해 중국어 스팸 필터 확장이 없다는 것입니다. (물론, 있을지도 모릅니다.) 그래서 그냥 만들어 버렸습니다. ^^;

방법은 대강 다음의 문서에 있으니,

Walkthrough: Creating Your First VSTO Add-In for Outlook
; https://learn.microsoft.com/en-us/visualstudio/vsto/walkthrough-creating-your-first-vsto-add-in-for-outlook

비주얼 스튜디오에서 "Visual C#" / "Office/SharePoint" / "VSTO Add-ins"의 "Outlook 2013 and 2016 VSTO Add-in" 프로젝트를 선택해 메일이 왔을 때의 이벤트 처리를 추가하고,

How to: Programmatically Perform Actions When an E-Mail Message Is Received
; https://learn.microsoft.com/en-us/visualstudio/vsto/how-to-programmatically-perform-actions-when-an-e-mail-message-is-received

메일의 제목에 2개 이상의 중국어 문자가 포함된 경우 스팸 메일로 간주하고 '정크 메일' 함으로 보내게 했습니다. 다음은 그에 대한 소스 코드입니다.

using Outlook = Microsoft.Office.Interop.Outlook;

namespace CharacterRangeFilter
{
    public partial class ThisAddIn
    {
        Outlook.NameSpace outlookNameSpace;
        Outlook.MAPIFolder inbox;
        Outlook.Items items;

        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            outlookNameSpace = this.Application.GetNamespace("MAPI");
            inbox = outlookNameSpace.GetDefaultFolder(
                    Microsoft.Office.Interop.Outlook.
                    OlDefaultFolders.olFolderInbox);

            items = inbox.Items;
            items.ItemAdd +=
                new Outlook.ItemsEvents_ItemAddEventHandler(items_ItemAdd);
        }

        void items_ItemAdd(object Item)
        {
            Outlook.MailItem mail = (Outlook.MailItem)Item;
            if (Item != null)
            {
                if (mail.MessageClass == "IPM.Note")
                {
                    if (HasChineseCharacters2More(mail) == true)
                    {
                        mail.Move(outlookNameSpace.GetDefaultFolder(
                            Microsoft.Office.Interop.Outlook.
                            OlDefaultFolders.olFolderJunk));
                    }
                }
            }
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        bool HasChineseCharacters2More(Outlook.MailItem mail)
        {
            if (string.IsNullOrEmpty(mail.Subject) == true)
            {
                return false;
            }

            string title = mail.Subject;
            int count = 0;

            // https://ko.wikipedia.org/wiki/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C_%EB%B8%94%EB%A1%9D
            foreach (char ch in title)
            {
                switch (ch)
                {
                    case char i when i >= 0x2e80 && i <= 0x2eff: // CJK Radicals Supplement
                        count++;
                        break;

                    case char i when i >= 0x2f00 && i <= 0x2fdf: // Kangxi Radicals
                        count++;
                        break;

                    case char i when i >= 0x3000 && i <= 0x303f: // CJK Symbols and Punctuation
                        count++;
                        break;

                    case char i when i >= 0x3400 && i <= 0x4dbf: // CJK Unified Ideographs Extension A
                        count++;
                        break;

                    case char i when i >= 0x4e00 && i <= 0x9fff: // CJK Unified Ideographs
                        count++;
                        break;

                        // for now, except for 2 SIP area
                        /*
                        2 SIP U+20000..U+2A6DF CJK Unified Ideographs Extension B
                        2 SIP U+2A700..U+2B73F CJK Unified Ideographs Extension C
                        2 SIP U+2B740..U+2B81F CJK Unified Ideographs Extension D
                        2 SIP U+2B820..U+2CEAF CJK Unified Ideographs Extension E
                        2 SIP U+2CEB0..U+2EBEF CJK Unified Ideographs Extension F
                        2 SIP U+2F800..U+2FA1F CJK Compatibility Ideographs Supplement
                        */
                }
            }

            return count > 1;
        }

        #region VSTO generated code

        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }
        
        #endregion
    }
}

규칙이 매우 간단한데, 일단 저 혼자 쓸 것이므로 이 정도면 충분하기에 정한 기준입니다. 위의 소스 코드는 현재 github에도 올렸으니, 사용자 정의 조건을 설정하는 창을 만들어 pull request를 보내주시면 언제든 ^^ 반영해드리겠습니다.

stjeong/CharacterRangeFilter 
; https://github.com/stjeong/CharacterRangeFilter

컴파일된 바이너리는 클릭원스를 이용했습니다. (VSTO add-in을 ClickOnce로 배포할 수 있다는 것은 처음 알았군요. ^^)

Deploying an Office Solution by Using ClickOnce
; https://learn.microsoft.com/en-us/visualstudio/vsto/deploying-an-office-solution-by-using-clickonce

위의 문서에 보면 VSTOInstaller를 이용한 방법도 나오는데,

%commonprogramfiles%\microsoft shared\VSTO\10.0\VSTOInstaller.exe

이번에는 그냥 ClickOnce로 했습니다. 하는 김에 Office Store에도 넣으려고 했는데 ^^

Make your solutions available in Microsoft AppSource and within Office
; https://learn.microsoft.com/en-us/office/dev/store/submit-to-appsource-via-partner-center

아쉽게도 지금 개발자 인증에 문제가 있어서 포기했습니다. (혹시, 다음번 기회가 되면 경험 삼아 올려봐야겠습니다.)




그냥 설치만 하고 싶으신 분들은, 다음의 절차를 따라야 합니다.

우선 인증서가 문제인데요, 제가 개인적인 목적으로 만든 것이라 정식 인증서 발급까지 받지는 못했습니다. 따라서, 테스트 인증서를 여러분들의 로컬 PC에 설치해야 하는데, 이를 위해 다음의 인증서를 다운로드하고,

http://sysnet.blob.core.windows.net/temp/stjeong.cer

관리자 권한의 cmd.exe 명령행 프롬프트를 띄운 후 다음과 같은 명령어로 등록해 줍니다.

C:\temp>certmgr.exe -add stjeong.cer -c -s -r localMachine Root
CertMgr Succeeded

C:\temp>certmgr.exe -add stjeong.cer -c -s -r localMachine TrustedPublisher
CertMgr Succeeded

[업데이트: 2018-10-04] 위의 과정을 처리해 주는 CertMgr2.exe를 만들었으니 http://sysnet.blob.core.windows.net/temp/office/CertMgr2.zip 파일을 다운로드 해 압축을 푼 후 실행만 하면 됩니다.

그다음, 아래의 경로를 방문해 setup.exe를 실행해 주면 됩니다.

http://sysnet.blob.core.windows.net/temp/office/setup.exe

정상적으로 설치된 경우, 아웃룩의 "Options" / "Add-ins" 영역에 다음과 같이 "CharacterRangeFilter" 확장이 보일 것입니다.

china_spam_filter_for_outlook_1.png

참고로, 테스트는 Windows 10 + .NET Framework 4.5.2 + 아웃룩 2016에서 한 것입니다. 그 외의 환경에서는 안 될 수도 있습니다




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

[연관 글]






[최초 등록일: ]
[최종 수정일: 3/6/2023]

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

비밀번호

댓글 작성자
 




... 46  47  48  49  50  51  52  53  54  55  56  57  58  59  [60]  ...
NoWriterDateCnt.TitleFile(s)
12135정성태2/6/202013312개발 환경 구성: 468. Nuget 패키지의 로컬 보관 폴더를 옮기는 방법 [2]
12134정성태2/5/202013449.NET Framework: 884. eBEST XingAPI의 C# 래퍼 버전 - XingAPINet Nuget 패키지 [5]파일 다운로드1
12133정성태2/5/202010714디버깅 기술: 161. Windbg 환경에서 확인해 본 .NET 메서드 JIT 컴파일 전과 후 - 두 번째 이야기
12132정성태1/28/202012286.NET Framework: 883. C#으로 구현하는 Win32 API 후킹(예: Sleep 호출 가로채기)파일 다운로드1
12131정성태1/27/202012333개발 환경 구성: 467. LocaleEmulator를 이용해 유니코드를 지원하지 않는(한글이 깨지는) 프로그램을 실행하는 방법 [1]
12130정성태1/26/20209821VS.NET IDE: 142. Visual Studio에서 windbg의 "Open Executable..."처럼 EXE를 직접 열어 디버깅을 시작하는 방법
12129정성태1/26/202015345.NET Framework: 882. C# - 키움 Open API+ 사용 시 Registry 등록 없이 KHOpenAPI.ocx 사용하는 방법 [3]
12128정성태1/26/202010136오류 유형: 591. The code execution cannot proceed because mfc100.dll was not found. Reinstalling the program may fix this problem.
12127정성태1/25/202010029.NET Framework: 881. C# DLL에서 제공하는 Win32 export 함수의 내부 동작 방식(VT Fix up Table)파일 다운로드1
12126정성태1/25/202010848.NET Framework: 880. C# - PE 파일로부터 IMAGE_COR20_HEADER 및 VTableFixups 테이블 분석파일 다운로드1
12125정성태1/24/20208718VS.NET IDE: 141. IDE0019 - Use pattern matching
12124정성태1/23/202010533VS.NET IDE: 140. IDE1006 - Naming rule violation: These words must begin with upper case characters: ...
12123정성태1/23/202012019웹: 39. Google Analytics - gtag 함수를 이용해 페이지 URL 수정 및 별도의 이벤트 생성 방법 [2]
12122정성태1/20/20209006.NET Framework: 879. C/C++의 UNREFERENCED_PARAMETER 매크로를 C#에서 우회하는 방법(IDE0060 - Remove unused parameter '...')파일 다운로드1
12121정성태1/20/20209584VS.NET IDE: 139. Visual Studio - Error List: "Could not find schema information for the ..."파일 다운로드1
12120정성태1/19/202011020.NET Framework: 878. C# DLL에서 Win32 C/C++처럼 dllexport 함수를 제공하는 방법 - 네 번째 이야기(IL 코드로 직접 구현)파일 다운로드1
12119정성태1/17/202011024디버깅 기술: 160. Windbg 확장 DLL 만들기 (3) - C#으로 만드는 방법
12118정성태1/17/202011681개발 환경 구성: 466. C# DLL에서 Win32 C/C++처럼 dllexport 함수를 제공하는 방법 - 세 번째 이야기 [1]
12117정성태1/15/202010685디버깅 기술: 159. C# - 디버깅 중인 프로세스를 강제로 다른 디버거에서 연결하는 방법파일 다운로드1
12116정성태1/15/202011150디버깅 기술: 158. Visual Studio로 디버깅 시 sos.dll 확장 명령어를 (비롯한 windbg의 다양한 기능을) 수행하는 방법
12115정성태1/14/202010933디버깅 기술: 157. C# - PEB.ProcessHeap을 이용해 디버깅 중인지 확인하는 방법파일 다운로드1
12114정성태1/13/202012779디버깅 기술: 156. C# - PDB 파일로부터 심벌(Symbol) 및 타입(Type) 정보 열거 [1]파일 다운로드3
12113정성태1/12/202013392오류 유형: 590. Visual C++ 빌드 오류 - fatal error LNK1104: cannot open file 'atls.lib' [1]
12112정성태1/12/20209988오류 유형: 589. PowerShell - 원격 Invoke-Command 실행 시 "WinRM cannot complete the operation" 오류 발생
12111정성태1/12/202013259디버깅 기술: 155. C# - KernelMemoryIO 드라이버를 이용해 실행 프로그램을 숨기는 방법(DKOM: Direct Kernel Object Modification) [16]파일 다운로드1
12110정성태1/11/202011859디버깅 기술: 154. Patch Guard로 인해 블루 스크린(BSOD)가 발생하는 사례 [5]파일 다운로드1
... 46  47  48  49  50  51  52  53  54  55  56  57  58  59  [60]  ...