NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 팁 앤 테크
  • 매뉴얼

    팁과 테크니컬 노하우를 확인하세요.

    팁 앤 테크

    팁과 테크니컬 노하우를 확인하세요.

    본 사이트의 컨텐츠는 저작권법의 보호를 받으므로 무단 복사, 게재, 배포 등을 금합니다.

    디자이너 3부 - 엔지엠 이미지 매크로 만들기. (프레임워크와 에디터)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 그동안 파이썬 매크로 만들기와 비교하면서 엔지엠 프레임워크로 매크로를 어떻게 만드는지 알아봤습니다. 파이썬의 경우 pyautogui라는 패키지가 있어서 쉽고 빠르게 마우스와 키보드를 제어하는 매크로를 만들 수 있었습니다. 엔지엠 프레임워크를 사용하면, 마우스와 키보드뿐만 아니라 이미지, 문자 판독등등 쉽게 처리가 가능합니다. 사실, 프레임워크가 아닌 에디터를 사용하면 더 쉽습니다-_-; 코딩을 몰라도 업무를 분석하고 구성할 수 있는 능력만 있으면 아무나 게임이나 업무를 자동화할 수 있습니다. (업무 분석, 구성, 응용력은 연습이 필요합니다.) 이전 글들을 학습하신 분들은 Visual Studio를 실행하고, 솔루션을 열어주세요. 솔루션이 없는 분들은 이 글에 첨부되어 있는 솔루션을 열어주세요.

    #region 참조
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Mouse = NGM.Utility.MouseKeyboardManager.MouseSimulator;
    using Keyboard = NGM.Utility.MouseKeyboardManager.KeyboardSimulator;
    using System.Windows.Forms;
    using System.Drawing;
    using System.Runtime.InteropServices;
    #endregion
    
    namespace ConsoleApp1
    {
        class Program
        {
            #region Windows API
            [DllImport("kernel32.dll")]
            static extern IntPtr GetConsoleWindow();
    
            [DllImport("user32.dll")]
            static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    
            const int SW_HIDE = 0;
            const int SW_SHOW = 1;
            #endregion
    
            static void Main(string[] args)
            {
                // 콘솔창이 표시되지 않도록 합니다.
                ShowWindow(GetConsoleWindow(), SW_HIDE);
    
                // 메모장을 클릭합니다.
                Mouse.Position = new Point(300, 100);
                Mouse.Click(Mouse.MouseButton.Left);
    
                // 메모장에서 키보드를 누르고 있는 상태입니다.
                foreach (char c in "안녕하세요. NGMsoftware입니다.")
                {
                    Keyboard.Write(c.ToString());
                }
    
                // 콘솔창을 표시합니다.
                ShowWindow(GetConsoleWindow(), SW_SHOW);
    
                // 콘솔 출력을 확인하기 위해 대기합니다. 아무키나 누르면 프로그램이 종료됩니다.
                Console.ReadLine();
            }
        }
    }

    gnAs2FX.png

     

     

    파이썬에서는 pip(Python Package Index)를 이용해서 원하는 패키지를 설치할 수 있습니다. 노드의 npm 또는 yarn과 같은 소프트웨어입니다. 엔지엠 프레임워크는 디자이너가 설치된 폴더에 패키지가 같이 설치됩니다. 파이썬이나 노드는 글로벌하게 패키지를 설치하거나 워크스페이스 또는 세션(Session)별로 관리됩니다. C#이나 Java같은 컴파일 언어들은 참조되는 모듈(자바는 패키지)이 프로젝트에 같이 있어야 합니다. Visual Studio의 우측 솔루션 탐색기에서 프로젝트를 선택하고 우클릭하세요. 그리고, "파일 탐색기에서 폴더 열기"를 클릭하세요.

    kUSmfJ6.png

     

     

    이 위치에 아래 파일을 복사해서 붙여넣기 하세요.

    • 32bit: C:\Program Files (x86)\NGMsoftware\NUI\x86\OpenCvSharpExtern.dll
    • 64bit: C:\Program Files\NGMsoftware\NUI\x64\OpenCvSharpExtern.dll

    jjn9eEP.png

     

     

    솔루션 탐색기 상단 메뉴의 오른쪽 마지막에 문서 그림 3개가 겹쳐져 보이는게 있을겁니다. "모든 파일 표시" 버튼을 체크하세요. 그러면, 프로젝트 아래 "OpenCvSharpExtern.dll" 파일이 표시됩니다. 아직 프로젝트에 추가된건 아니고, 파일만 추가된 상태입니다.

    gzBuvCT.png

     

     

    "OpenCvSharpExtern.dll"을 우클릭하고 "프로젝트에 포함"을 클릭하세요.

    8hMUngH.png

     

     

    "OpenCvSharpExtern.dll"을 다시 우클릭하고, 속성을 클릭하세요.

    S2C1RmU.png

     

     

    "출력 디렉터리에 복사" 옵션을 "새 버전이면 복사"로 변경해줍니다. 이렇게 설정하면 프로젝트를 컴파일(빌드)할 때 해당 파일이 배포 위치로 복사됩니다.

    wkvdTmM.png

     

     

    코드를 아래와 같이 변경해주세요.

    #region 참조
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Mouse = NGM.Utility.MouseKeyboardManager.MouseSimulator;
    using Keyboard = NGM.Utility.MouseKeyboardManager.KeyboardSimulator;
    using System.Windows.Forms;
    using System.Drawing;
    using System.Runtime.InteropServices;
    #endregion
    
    namespace ConsoleApp1
    {
        class Program
        {
            #region Windows API
            [DllImport("kernel32.dll")]
            static extern IntPtr GetConsoleWindow();
    
            [DllImport("user32.dll")]
            static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    
            const int SW_HIDE = 0;
            const int SW_SHOW = 1;
            #endregion
    
            static void Main(string[] args)
            {
                // 콘솔창이 표시되지 않도록 합니다.
                ShowWindow(GetConsoleWindow(), SW_HIDE);
    
                // 가상 엔지엠 플레이어 컨테이너를 만듭니다.
                var mv = new Designer.ComponentDefault.MainView();
                // 모든 로그를 표시하도록 옵션을 변경합니다.
                AllLogOn(mv);
                // 엔지엠 플레이어가 로그를 기록하면 이벤트가 발생합니다.
                mv.LogReceived += Mv_LogReceived;
                // 가상 스크립트를 만듭니다.
                var sv = new Designer.Component.ScriptView(mv, "./Dummy.ngs");
                // 액션을 추가합니다. "이미지서치"는 스크립트에 추가된 액션의 이름입니다.
                // 이름은 아무렇게나 지어도 되지만, 중복되면 안됩니다.
                var tn = sv.TreeView.Nodes.Add("이미지서치");
                tn.Tag = new NGM.Models.Condition.MatchImageModel()
                {
                    FunctionKey = NGM.Definition.FunctionKey.CONDITION_MATCH_IMAGE,
                    ImagePath = @"C:\Users\ngmas\Desktop\Cat.png",
                    MouseAction = NGM.Definition.MouseClickAction.LeftClick
                };
    
                // 스크립트를 실행합니다.
                sv.Play();
    
                // 숨긴 콘솔을 다시 표시합니다.
                //ShowWindow(GetConsoleWindow(), SW_SHOW);
    
    
                // 콘솔 출력을 확인하기 위해 대기합니다. 아무키나 누르면 프로그램이 종료됩니다.
                Console.ReadLine();
            }
    
            static void AllLogOn(NGM.Interface.IMainView mv)
            {
                mv.IsOutput = true;
                mv.ShowApplicationOutput = true;
                mv.ShowConditionOutput = true;
                mv.ShowDebugOutput = true;
                mv.ShowDefaultOutput = true;
                mv.ShowFunctionOutput = true;
                mv.ShowHardwareOutput = true;
                mv.ShowKeyboardOutput = true;
                mv.ShowMemoryOutput = true;
                mv.ShowMouseOutput = true;
                mv.ShowTimeOutput = true;
            }
    
            private static void Mv_LogReceived(object sender, NGM.Events.LogWriteArgs e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }

     

    코드가 복잡해 보이지만, 디버깅을 위한 함수를 제외하면 그리 어려운 코드는 없습니다. 예제에서는 고양이 이미지를 찾아서 클릭하도록 처리 했습니다. 찾을 고양이 이미지를 먼저 만들어야겠죠? 아래와 같이 엔지엠 에디터를 실행하고, 메뉴의 파일 > 새로 만들기 > 이미지를 클릭하세요.

    LvZQGwP.png

     

     

    크롬을 실행하고, 구글로 이동합니다. 그리고, 고양이를 검색해보세요.

    3LFjV6J.png

     

     

    아래 동영상을 참고해서 Cat.png 이미지를 바탕화면에 저장하세요.

    S94hKFN.gif

     

     

    엔지엠 에디터에서 작업하면 쉬운데요. 프레임워크로 작업하려다보니 해야할 일들이 많군요^^; 사실 엔지엠 에디터가 아닌 다른 캡쳐 도구를 사용해서 png 이미지로 저장해도 됩니다. 아무튼~ 찾을 이미지를 바탕화면에 저장했으니 잘 동작하는지 테스트 해봐야겠죠? 비주얼 스튜디오에서 F5를 눌러서 실행하세요.

    rxr0bUk.gif

     

     

    바탕화면에 저장한 고양이를 찾아서 클릭하는걸 알 수 있습니다. 여기서 핵심은 아래 코드입니다.

    // 액션을 추가합니다. "이미지서치"는 스크립트에 추가된 액션의 이름입니다.
    // 이름은 아무렇게나 지어도 되지만, 중복되면 안됩니다.
    var tn = sv.TreeView.Nodes.Add("이미지서치");
    tn.Tag = new NGM.Models.Condition.MatchImageModel()
    {
        FunctionKey = NGM.Definition.FunctionKey.CONDITION_MATCH_IMAGE,
        ImagePath = @"C:\Users\ngmas\Desktop\Cat.png",
        MouseAction = NGM.Definition.MouseClickAction.LeftClick
    };

     

    모델(MatchImageModel)에는 필수로 입력되어야 하는 FunctionKey가 존재합니다. 이 키는 액션이 어떤 동작을 해야 하는지 식별할 수 있는 유니크한 아이디입니다. 그리고, 모델의 종류에 따라 속성들이 달라지게 됩니다. 이미지 조건 관련된 모델들은 전부 ImagePath 속성을 가집니다. 이미지에 필터를 적용시킨 이미지를 사용하려면 ImageInfo 속성을 사용하세요. 이 속성은 엔지엠의 ngi 확장자를 가진 이미지 파일입니다.

    FunctionKey = NGM.Definition.FunctionKey.CONDITION_MATCH_IMAGE,

     

    이외에도 수많은 모델과 속성들이 존재합니다. 앞서 배운 마우스와 키보드도 아래와 같이 처리할 수 있습니다. 이외에도 엔지엠 에디터에서 제공하는 모든 기능을 코딩 방식으로 이용할 수 있습니다. 또한, MainView에서 제공하는 Before, After 이벤트를 이용하면 매크로가 실행되는 중간에 사용자가 원하는 처리를 추가할 수 있습니다. 조건에 따라서 추가적인 내용을 넣어도 됩니다.

    #region 참조
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Mouse = NGM.Utility.MouseKeyboardManager.MouseSimulator;
    using Keyboard = NGM.Utility.MouseKeyboardManager.KeyboardSimulator;
    using System.Windows.Forms;
    using System.Drawing;
    #endregion
    
    namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                // 매인뷰를 생성합니다.
                var mv = new Designer.ComponentDefault.MainView();
    
                // 모든 로그를 출력하도록 변경해줍니다.
                DisplayAllLog(mv);
    
                // 로그가 기록되면 이벤트를 발생 시킵니다.
                mv.LogReceived += Mv_LogReceived;
    
                // 매크로 엔진에서 가상으로 실행할 스크립트 뷰를 생성합니다. 
                // isBackground 파라메터를 false로 명시하지 않으면 뷰를 생성하지 않고 백그라운드로 실행됩니다.
                var sv = new Designer.Component.ScriptView(mv, "/Dummy.ngs");
    
                // 스크립트 뷰는 액션을 순차적으로 실행하기 위한 TreeView를 제공합니다.
                TreeNode tn = sv.TreeView.Nodes.Add("M", "Mouse");
    
                // 내문서를 클릭합니다.
                tn.Tag = new NGM.Models.Mouse.ClickModel() {
                    BeforeDelay = 500,
                    FunctionKey = NGM.Definition.FunctionKey.MOUSE_CLICK,
                    MousePoint = new Point(40, 30) };
    
                tn = sv.TreeView.Nodes.Add("M", "Mouse");
    
                // 내 PC를 클릭합니다.
                tn.Tag = new NGM.Models.Mouse.ClickModel() {
                    BeforeDelay = 500,
                    FunctionKey = NGM.Definition.FunctionKey.MOUSE_CLICK,
                    MousePoint = new Point(40, 110) };
    
                tn = sv.TreeView.Nodes.Add("M", "Mouse");
    
                // 네트워크를 클릭합니다.
                tn.Tag = new NGM.Models.Mouse.ClickModel() {
                    BeforeDelay = 500,
                    FunctionKey = NGM.Definition.FunctionKey.MOUSE_CLICK,
                    MousePoint = new Point(40, 200) };
    
                tn = sv.TreeView.Nodes.Add("M", "Mouse");
    
                // 휴지통을 클릭합니다.
                tn.Tag = new NGM.Models.Mouse.ClickModel() {
                    BeforeDelay = 500,
                    FunctionKey = NGM.Definition.FunctionKey.MOUSE_CLICK,
                    MousePoint = new Point(40, 280) };
    
                // 스크립트를 실행합니다.
                sv.Play();
    
                // 콘솔 출력을 확인하기 위해 대기합니다. 아무키나 누르면 프로그램이 종료됩니다.
                Console.ReadLine();
            }
    
            static void DisplayAllLog(NGM.Interface.IMainView mv)
            {
                mv.IsOutput = true;
                mv.ShowApplicationOutput = true;
                mv.ShowConditionOutput = true;
                mv.ShowDebugOutput = true;
                mv.ShowDefaultOutput = true;
                mv.ShowFunctionOutput = true;
                mv.ShowHardwareOutput = true;
                mv.ShowKeyboardOutput = true;
                mv.ShowMemoryOutput = true;
                mv.ShowMouseOutput = true;
                mv.ShowTimeOutput = true;
            }
    
            private static void Mv_LogReceived(object sender, NGM.Events.LogWriteArgs e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }

     

    디자이너 또는 프레임워크 방식으로 코딩한다는건 개발자라도 어려운일입니다. 그래서, 엔터프라이즈 라이센스를 가진 분께는 가이드 문서를 드리고 있습니다.

    C4Sm5PA.png

     

     

    개발하는데 필요한 클래스와 함수 및 관계를 파악할 수 있습니다.

    0Veey4k.png

     

     

    계속해서 설명을 추가하고 있는데요. 작업이 더딘 부분이 있네요. 수백만줄에 달하는 코드를 정리하다보면... 끝이 안보여서 그런지 금방 지칩니다-_-;

    fcSu4S0.png

     

     

    문서는 설명을 확인하는 용도로 사용하시고, 빠르게 원하는 액션을 추가하려면 에디터를 사용해야 합니다. 아래 그림과 같이 스크립트를 추가하고, 코딩에 사용할 액션을 추가합니다. 그리고, 에디터의 하단에 "소스 보기" 버튼을 클릭하세요. 이 액션의 FunctionKey와 사용할 수 있는 속성(Property)들을 확인할 수 있습니다. 또한, 사용되지 않는 속성들은 Obsolete(구식, 사용되지 않는) 메시지가 표시되니 주의해야 합니다.

    dwHjXlo.png

     

     

    이렇게해서 엔지엠 프레임워크로 이미지를 찾아서 클릭하는 간단한 매크로를 만들어봤습니다. 당연한 말이겠지만~ 개발자가 봐도 어려운 내용들입니다. 일반인분들이 뭔가 자신만의 작품(?)을 만드는게 아니라면 엔지엠 에디터를 사용하는게 좋습니다. 파이썬이나 루아 또는 Java, C, C++로 매크로를 간단하게 만드는건 누구나 할 수 있는일입니다. 하지만, 완성도 있게 만드는건 또 다른 문제죠~ 특히나~ 범용적으로 만드는건 더욱 더 어려운 작업이구요. 이정도 수준의 간단한 작업들은 몇십만원에 만들어드릴 수 있습니다. 하지만, 매크로를 몇만원에 제작 의뢰하시는 것들은 제작이 어렵습니다. 노력대비 비용을 생각해보면 안하는게 맞죠^^;

     

    다음에는 좀 더 다양한 내용으로 예제를 만들어보도록 할께요. 혹시나 궁금한 내용이나 질문이 있으면 남겨주세요! 간단한 것들은 예제를 만들어서 공유하도록 하겠습니다.

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.